If I have structure definitions, for example, like these:
struct Base {
int foo;
};
struct Derived {
int foo; // int foo is common for both definitions
char *bar;
};
Can I do something like this?
void foobar(void *ptr) {
((struct Base *)ptr)->foo = 1;
}
struct Derived s;
foobar(&s);
In other words, can I cast the void pointer to Base * to access its foo member when its type is actually Derived *?
Many real-world C programs assume the construct you show is safe, and there is an interpretation of the C standard (specifically, of the “common initial sequence” rule, C99 §6.5.2.3 p5) under which it is conforming. Unfortunately, in the five years since I originally answered this question, all the compilers I can easily get at (viz. GCC and Clang) have converged on a different, narrower interpretation of the common initial sequence rule, under which the construct you show provokes undefined behavior. Concretely, experiment with this program:
When compiling with optimization enabled (and without
-fno-strict-aliasing), both GCC and Clang will assume that the two pointer arguments totestABcannot point to the same object, so I get output likeThey do not make that assumption for
testAC, but — having previously been under the impression thattestABwas required to be compiled as if its two arguments could point to the same object — I am no longer confident enough in my own understanding of the standard to say whether or not that is guaranteed to keep working.