Shao Miller
6/17/2011 8:52:00 PM
On 6/16/2011 3:50 AM, Lauri Alanko wrote:
> Given:
>
> typedef struct { int foo; } Bar;
>
> The following is legal (N869 6.7.2.1#12):
>
> Bar b = { 42 };
> int* ip =&bar.foo;
> Bar* bp = (Bar*) ip;
> assert(bp->foo == 42);
>
> But this, to my understanding, might not be:
>
> int i = 42;
> int* ip =&i;
> Bar* bp = (Bar*) ip;
> assert(bp->foo == 42);
>
> The only practical problem I can think of here is that Bar and int
> might have different alignments for some reason.
Agreed. They might have different alignment requirements. The
alignment of 'int' would have to be satisfied by the alignment of 'Bar',
but not vice versa.
>
> However, all structs are guaranteed to have the same alignment
> (6.2.5#27), so how about the following?
>
As Mr. James Kuyper already pointed out, that point is in regards to
pointers. Thus a conversion of a 'struct XXX *' to a 'struct YYY *' is
defined regardless of 'XXX' and 'YYY'; the alignment of the pointer
types is good[6.3.2.3p7]. Same with unions.
> typedef struct { Bar bar; } Baz;
>
> Bar b = { 42 };
> Baz* zp = (Baz*)&b;
> assert(zp->bar.foo == 42);
>
> At this point, although I'm guessing this isn't strictly conforming, I
> can't think of any real-world reason why this wouldn't work.
>
> Anyone?
Same problem. The alignment of 'Bar' would have to be satisfied by the
alignment of 'Baz', but not vice versa. If a 'Bar' could only be at
every 4 bytes and a 'Baz' could only be at every 12 bytes, 'b' might be
at 8 bytes. An implementation might notice such an attempt even at
translation-time, since we can discuss it here by looking at it. :)