Is a pointer to the struct aligned as if it were a pointer to the first element?
or
Is a conversion between a pointer to a struct and a pointer to the type of its first member (or visa versa) ever UB?
(I hope they are the same question...)
struct element
{
tdefa x;
tdefb y;
};
int foo(struct element* e);
int bar(tdefa* a);
~~~~~
tdefa i = 0;
foo((struct element*)&i);
or
struct element e;
bar((tdefa*)&e);
Where tdefa
and tdefb
could be defined as any type
Background:
I asked this question and a user in a comment on one of the answers brought up C11 6.3.2.3 p7 that states:
"A pointer to an object type may be converted to a pointer to a different object type. If the resulting pointer is not correctly aligned for the referenced type, the behavior is undefined"
However I am having trouble working out when this would become an issue, my understanding was that padding would allow all members of the struct to be aligned correctly. Have I misunderstood?
and if:
struct element e;
tdefa* a = &e.x;
would work then:
tdefa* a = (tdefa*)&e;
would too.
A pointer to a structure always points to its initial member.
Here is the citation directly from C99 standard (6.7.2.1, paragraph 13), emphasis mine:
As for your
foo
andbar
examples:The call to
bar
will be fine, asbar
expects atdefa
, which is exactly what it's getting.The call to
foo
, however, is problematic.foo
expects a fullstruct element
, but you're only passing atdefa
(while the struct consists of bothtdefa
andtdefb
).There is never any initial padding; the first member of a struct is required to start at the same address as the struct itself.
You can always access the first member of a struct by casting a pointer to the whole struct, to be a pointer to the type of the first member.
Your
foo
example might run into trouble becausefoo
will be expecting its argument to point to astruct element
which in fact it does not, and there might be an alignment mismatch.However the
bar
example and the final example is fine.