Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is casting a struct T* to a struct C* undefined behavior, if T's first field is a C?

While trying to debug a problem I'm having using Speex, I noticed that it (well, not just Speex, but some example code as well) does the following:

  • Return a pointer to EncState from an initialization function
  • Cast that pointer to a void pointer
  • Store the void pointer
  • (elsewhere)
  • Cast the void pointer to a pointer to pointer to SpeexMode
  • Dereference the pointer

It so happens that the definition of EncState starts with a field of type SpeexMode *, and so the integer values of a pointer to the first field and a pointer to the struct happen to be the same. The dereference happens to work at runtime.

But... does the language actually allow this? Is the compiler free to do whatever it wants if it compiles this? Is casting a struct T* to a struct C* undefined behavior, if T''s first field is a C`?

like image 207
Craig Gidney Avatar asked Jan 24 '13 21:01

Craig Gidney


1 Answers

From the C11 standard:

(C11 §6.7.2.1.15: "A pointer to a structure object, suitably converted, points to its initial member ... and vice versa. There may be unnamed padding within as structure object, but not at its beginning.")

Which means that the behavior you see is allowed and guaranteed.

like image 135
pmr Avatar answered Nov 15 '22 07:11

pmr