Reputation: 7925
Suppose I have a struct like that:
typedef struct {
char *str;
int len;
} INS;
And an array of that struct.
INS *ins[N] = { &item, &item, ... }
When i try to access its elements, not as pointer, but as struct itself, all the fields are copied to a temporary local place?
for (int i = 0; i < N; i++) {
INS in = *ins[i];
// internaly the above line would be like:
// in.str = ins[i]->str;
// in.len = ins[i]->len;
}
?
So as I increase the structure fields that would be a more expensive assignment operation?
Upvotes: 2
Views: 295
Reputation: 222923
The compiler may optimize away the copy of the structure and instead either access members directly from the array to supply the values needed in your C code that uses the copy or may copy just the individual members you use. A good compiler will do this.
Storing values via pointers can interfere with this optimization. For example, suppose your routine also has a pointer to int, p
. When the compiler processes your code INS in = *ins[i]
, it could “think” something like this: “Copying ins[i]
is expensive. Instead, I will just remember that in
is a copy, and I will fetch members for it later, when they are used.” However, if your code contains *p = 3
, this could change ins[i]
, unless the compiler is able to deduce that p
does not point into ins[i]
. (There is a way to help the compiler make that deduction, with the restrict
keyword.)
In summary: Operations that look expensive on the surface might be implemented efficiently by a good compiler. Operations that look cheap might be expensive (writing to *p
breaks a big optimization). Generally, you should write code that clearly expresses your algorithm and let the compiler optimize.
To expand on how the compiler might optimize this. Suppose you write:
for (int i = 0; i < N; i++) {
INS in = *ins[i];
...
}
where the code in “...” accesses in.str and in.len but not any of the other 237 members you add to the INS struct. Then the compiler is free to, in effect, transform this code into:
for (int i = 0; i < N; i++) {
char *str = *ins[i].str;
int len = *ins[i].len;
...
}
That is, even though you wrote a statement that, on the surface, copies all of an INS struct, the compiler is only required to copy the parts that are actually needed. (Actually, it is not even required to copy those parts. It is only required to produce a program that gets the same results as if it had followed the source code directly.)
Upvotes: 1
Reputation: 59811
Yes, struct have value semantics
in C. So assigning a struct to another will result in a member-wise copy. Keep in mind that the pointers will still point to the same objects.
Upvotes: 1
Reputation: 70422
The structure assignment behaves like a memcpy
. Yes, it is more expensive for a larger structure. Paradoxically, the larger your structure becomes, the harder it is to measure the additional expense of adding another field.
Upvotes: 1
Reputation: 477120
Correct, in
is a copy of *ins[i]
.
Never mind your memory consumption, but your code will most likely not be correct: The object in
dies at the end of the loop body, and any changes you make to in
have no lasting effect!
Upvotes: 2