I was currently reading about some strict aliasing rules, and I was wondering whether casting a pointer to an incomplete struct is undefined behavior.
Example 1:
#include <stdlib.h>
struct abc;
int main(int argc, char *argv[])
{
struct abc *mystruct;
char *buf;
buf = malloc(100);
mystruct = (struct abc*)buf;
// and then mystruct could be submitted to a function, where it is
// casted back to a "char *", the "struct abc" will never be completed.
return 0;
}
Example 2:
struct abc1;
struct abc2;
int foo(struct abc1 *mystruct1)
{
struct abc2 *mystruct2;
mystruct2 = (struct abc2 *)mystruct1;
// and then mystruct2 could be submitted to a function, where it is
// casted to a "char *", both structs stay incomplete.
return 0;
}
So, my question: Is casting pointers to incomplete structs like in those two examples prohibited by the c11 standard, and if so, which part of the standard does forbid it?
One key relevant part of the standard is C11 §6.2.5 Types ¶28:
28 A pointer to void shall have the same representation and alignment requirements as a pointer to a character type.48) Similarly, pointers to qualified or unqualified versions of compatible types shall have the same representation and alignment requirements. All pointers to structure types shall have the same representation and alignment requirements as each other. All pointers to union types shall have the same representation and alignment requirements as each other. Pointers to other types need not have the same representation or alignment requirements.
48) The same representation and alignment requirements are meant to imply interchangeability as arguments to functions, return values from functions, and members of unions.
Another is §6.3 Conversions and particularly §6.3.2.3 Pointers ¶7:
7 A pointer to an object type may be converted to a pointer to a different object type. If the resulting pointer is not correctly aligned68) for the referenced type, the behavior is undefined. Otherwise, when converted back again, the result shall compare equal to the original pointer. When a pointer to an object is converted to a pointer to a character type, the result points to the lowest addressed byte of the object. Successive increments of the result, up to the size of the object, yield pointers to the remaining bytes of the object.
68) In general, the concept ''correctly aligned'' is transitive: if a pointer to type A is correctly aligned for a pointer to type B, which in turn is correctly aligned for a pointer to type C, then a pointer to type A is correctly aligned for a pointer to type C.
Thus, my understanding is that there is no problem with either example code fragment shown in the question. The structure types are incomplete, but that is not a problem for the operations shown. The 'and then' sections of the code need not be problematic — it depends on what is actually there.