[RFC] ignoring type alias conflicts between structures and scalars

Joseph S. Myers joseph@codesourcery.com
Thu Nov 25 18:03:00 GMT 2004


On Thu, 25 Nov 2004, Nathan Sidwell wrote:

> I don't think Joseph's example of
> 	struct float_int_s {float f; int i;};
>         int i;
>         ((float_int_s *)&((&i)[1]))[-1].i
> 
> being possibly valid is actually valid.  Notice this is forming the address

That wasn't my example :-).  My example was (&(((T*)(char*)&v)->i))[-1] 
(with T being float_int_s and v being i above), where float and int are 
supposed to be the same size with no padding in the structure.

Most cases of pointer conversion, where the pointers are properly aligned, 
are unspecified rather than undefined.  But the resulting pointer still 
has to be a valid pointer (not a trap representation) pointing somewhere 
and given that we document the implementation-defined pointer-integer 
conversions we'd have grave difficulty hooking anything on the conversion 
making a pointer have a different value from the one it started with, as 
opposed to saying that certain *dereferences* are undefined.

For the question of whether &(((T*)(char*)&v)->i) involves undefined 
behavior, you need to know whether an object access is taking place even 
though the address is being taken, which is unclear (the definition of 
unary & has nothing special for structure and union references).  However 
the examples given for flexible array members clearly contemplate being 
able to take their addresses even when the memory for the members isn't 
present, with only subsequent dereferences being undefined.

It is also unclear whether in general an access of a structure or union 
member counts as just one of that member (which might not require the 
whole structure or union to be present) or as one of the whole structure 
or union, but Nick Maclaren's "What is an Object?" (WG14 reflector 9350) 
points out that it must be considered to be just that member to avoid 
rendering such common usages as

    typedef struct {int a; double b; int c;} COMPOSITE;

        COMPOSITE composite = {0,0.0,0};

        composite.a += (composite.c = 0);

undefined by sequence point rules, as they would be if the relevant object 
being modified twice between sequence points were the whole structure.

-- 
Joseph S. Myers               http://www.srcf.ucam.org/~jsm28/gcc/
    jsm@polyomino.org.uk (personal mail)
    joseph@codesourcery.com (CodeSourcery mail)
    jsm28@gcc.gnu.org (Bugzilla assignments and CCs)



More information about the Gcc mailing list