Generally it is preferred to pass pointer to structure to a function in C, in order to avoid copying during function call. This has an unwanted side effect that the called function can modify the elements of the structure inadvertently. What is a good programming practice to avoid such errors without compromising on the efficiency of the function call ?
-
possible duplicate of [Is it better in C++ to pass by value or pass by constant reference?](http://stackoverflow.com/questions/270408/is-it-better-in-c-to-pass-by-value-or-pass-by-constant-reference) – 2501 Oct 17 '14 at 16:40
-
Is this a test question? (just curious) – ryyker Oct 17 '14 at 16:45
3 Answers
Pass a pointer-to-const is the obvious answer
void foo(const struct some_struct *p)
That will prevent you from modifying the immediate members of the struct inadvertently. That's what const
is for.
In fact, your question sounds like a copy-paste from some quiz card, with const
being the expected answer.

- 312,472
- 42
- 525
- 765
In general, when it comes to simple optimizations like what you've described, it is often preferable to use a pointer-to-struct
rather than passing a struct
itself, as passing a whole struct
means more overhead from extra data being copied onto the call stack.
The example below is a fairly common approach:
#include <errno.h>
typedef struct myStruct {
int i;
char c;
} myStruct_t;
int myFunc(myStruct_t* pStruct) {
if (!pStruct) {
return EINVAL;
}
// Do some stuff
return 0;
}
If you want to avoid modifying the data passed to the function, just make sure that the data is immutable by modifying the function prototype.
int myFunc(const myStruct_t* pStruct)
You will also benefit from reading up on "const correctness".
-
How does this address _unwanted side effect that the called function can modify the elements_ ? – ryyker Oct 17 '14 at 16:47
-
-
1
-
@ryyker How ironic :) We both committed the same foul, though **I** did start it. – Cloud Oct 17 '14 at 16:49
A very common idiom, particularly in unix/posix style system code is to have the caller allocate a struct, and pass a pointer to that struct through the function call.
This is a little different than what I think your asking about where you are passing data into a function with a struct (where as others have mention you may the function to treat the struct as const). In these cases, the struct is empty (or only partially full) before the function call. The caller will do something like allocate an empty struct and then passes a pointer to this struct. Probably different than your general question, but relevant to the discussion I think.
This accomplishes a couple handy things. It avoids copying a possibly large structure, also it lets the caller fill in some fields and the callee to fill out other (giving an effective shared space for communication).
The most important aspect to this idiom is that the caller has full control over the allocation of the struct. It can have it on the stack, heap, reuse the same one repeatedly, but where it comes from the caller is responsible for the handling the memory.
This is one of the problems with passing around struct pointers; you can easily lose track of who allocated the struct and whose responsibility it is to free it. This idiom gives you the advantage of not having to copy the struct around, while making it clear who has the job of free'ing the memory is.

- 2,226
- 16
- 13
-
1You had me on board until the last paragraph. It should never boil down to losing track of who owns an object/memory-block and how it was allocated. Modern IDEs and tools make this a non-issue. – Cloud Oct 17 '14 at 18:43
-
You shouldn't lose track of who owns a hunk of memory, of course. The ease with which you can do so varies. Keep in mind we're talking about C here, not C++. C++ makes memory allocation a different story entirely. – D'Nabre Oct 19 '14 at 08:22
-
I agree they are different, I just always found C easier to keep track of memory in than C++. In C, it's very cut and dry. In C++, unless you adhere to textbook "rule of three", etc approaches, one must keep track of the nuances between constructors, copy constructors, assignment constructors, virtual destructors, etc. – Cloud Oct 20 '14 at 02:38