The following code crashes my microprocessor at runtime.
struct dummytype dummy;
struct crummytype crummy;
*(unsigned int*)&dummy = *(unsigned int*)&crummy;
Assuming both structs are the same size, is there something about this code that is not valid C? Is its validity contingent on anything particular?
This is only valid if both structures have an unsigned int
as the first member.
C99 §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.
Putting that simply, given an address of a structure object, you can cast that address to a pointer-to-first-member-type:
struct A
{
unsigned int n;
char junk[5];
};
struct A a;
unsigned int *p = (unsigned int *)&a; // OK. pointer is proper for first member type
unsigned long*x = (unsigned long *)&a; // BAD
In short, your code is only legitimate if both structure types have an unsigned int
for their first member. Anything else is undefined behavior (void *
not withstanding, but since it is non-dereferencable, it really isn't applicable here). Each structure type being "big enough" to hold an unsigned int
isn't enough. Their first member must actually be an unsigned int
.