Hi, I really do like the relative simplicity of plain c and recently have become curious about doing some basic object oriented things in plain c such as inheritance. I have read about how type punning (casting a pointer to different types) is not strictly allowed by the c standard and may cause serious bugs with certain compilers or compiler options, and that using unions tricks can be similarly problematic. The obvious solution to me is the following, for example:

What seems strange to me though is that while this doesn't seem to violate the c standard, just like type punning, &(aCowboy->super) does return the same address as &myCowboy, but as a different pointer type. It therefor is hard for me to believe that type punning is any less correct than my solution OR that my solution is any more correct than type punning (and how could my solution not be correct?)

I can't speak to what the standard says (.oisyn will no doubt weigh in on it ), but I know the Windows API, for one, relies heavily on "type punning" e.g. to be able to extend a structure with new members in a later version of Windows.

And of course, the memory layout of the cowboy struct in your example is just what a typical C++ compiler is doing internally when you have cowboy derived from person. It's a pretty safe bet this sort of thing will work on any of the standard PC/Mac platforms. (I wouldn't care to speculate what might happen on some oddball embedded platform or something like that...but I guess PC/Mac is likely what you care about anyway...)

Ah, thank you for making me look in my favorite document, the C1X draft.

I have read about how type punning (casting a pointer to different types) is not strictly allowed by the c standard and may cause serious bugs with certain compilers or compiler options...

You can safely convert any pointer to an object type to a pointer to another object type (I suppose this is what you need). You can safely convert pointers to integers, but the implementation defines the semantics of this conversion. You can safely convert integers to pointers, but the result is defined by the specific implementation. You can convert a pointer to a pointer of a character type which allows you to access the individual bytes of the representation.

I can't speak to what the standard says (.oisyn will no doubt weigh in on it )

I woke up this morning with a sudden strong feeling that my help was needed somewhere in this universe.

Anyway, the person struct and the person-part of cowboy are layout compatible. You can safely convert a cowboy* to a person* and access the person's members. Basically, if you recursively "unfold" each struct definition into their members, and you put the types of all the members in a list, two structs are layout compatible up until a certain point if the lists are equivalent up until that point.

So, person is a { char* }, cowboy is a { char*, char* }, therefore person and cowboy are layout-compatible for the first char*.