http://cellperformance.beyond3d.com/articles/2006/06/understanding-strict-aliasing.html
As an add-on to the accepted answer, here is the full citation from the standard, with the important part highlighted that the other answer omitted, and one more:
6.7.2.1-13: Within a structure object, the non-bit-field members and the units in
which bit-fields reside have addresses that increase in the order in
which they are declared. A pointer to a structure object, suitably
converted, points to its initial member (or if that member is a
bit-field, then to the unit in which it resides), and vice versa.
There may be unnamed padding within a structure object, but not at its
beginning.
6.3.2.3-7: A pointer to an object or incomplete type may be converted to a pointer to a different object or incomplete type. If the
resulting pointer is not correctly aligned for the pointed-to type,
the behavior is undefined. Otherwise, when converted back again, the
result shall compare equal to the original pointer. [...]
I find your example to be a perfect place for a void pointer:
int age(void *object) {
Why? Because your obvious intention is to give different "object" types to such a function, and it gets the information according to the encoded type. In your version, you need a cast each time you call the function: age((object_t*)person);
. The compiler will not complain when you give the wrong pointer to it, so there is no type safety involved, anyway. Then you can as well use a void pointer and avoid the cast when calling the function.
Alternatively you could call the function with age(&person->object)
, of course. Each time you call it.
int type
to check the type then cast it correctly. – Prehistoryobject_t
has nothing to do withperson_t
? – Sterileperson_t*
as anobject_t*
but the other way. And that other way is unsafe even with the check ontype
because it could be cheated. – Ramsdenperson_t
includesobject_t
: aliasing is allowed.object_t
does not includeperson_t
: aliasing is not allowed. – Ramsden