On October 29, 2017 2:46:42 AM GMT+01:00, Yubin Ruan <ablacktsh...@gmail.com> 
wrote:
>On 10/27/2017 04:54 PM, Richard Biener wrote:
>> On Fri, Oct 27, 2017 at 3:00 PM, Yubin Ruan <ablacktsh...@gmail.com>
>wrote:
>>> +Cc gcc-list.
>>>
>>> Does any gcc developer have any comments?
>> 
>> See PR82224.  The code is valid.
>> 
>>> On Mon, Sep 25, 2017 at 01:41:55PM -0700, Myriachan wrote:
>>>> This question that "supercat" posted on Stack Overflow ran into an
>>>> interesting problem:
>>>>
>>>>
>https://stackoverflow.com/questions/46205744/is-this-use-of-unions-strictly-conforming/
>>>>
>>>> A copy of the code involved is as follows:
>>>>
>>>> struct s1 {unsigned short x;};
>>>> struct s2 {unsigned short x;};
>>>> union s1s2 { struct s1 v1; struct s2 v2; };
>>>>
>>>> static int read_s1x(struct s1 *p) { return p->x; }
>>>> static void write_s2x(struct s2 *p, int v) { p->x=v;}
>>>>
>>>> int test(union s1s2 *p1, union s1s2 *p2, union s1s2 *p3)
>>>> {
>>>>   if (read_s1x(&p1->v1))
>>>>   {
>>>>     unsigned short temp;
>>>>     temp = p3->v1.x;
>>>>     p3->v2.x = temp;
>>>>     write_s2x(&p2->v2,1234);
>>>>     temp = p3->v2.x;
>>>>     p3->v1.x = temp;
>>>>   }
>>>>   return read_s1x(&p1->v1);
>>>> }
>>>> int test2(int x)
>>>> {
>>>>   union s1s2 q[2];
>>>>   q->v1.x = 4321;
>>>>   return test(q,q+x,q+x);
>>>> }
>>>> #include <stdio.h>
>>>> int main(void)
>>>> {
>>>>   printf("%d\n",test2(0));
>>>> }
>>>>
>>>>
>>>> Both GCC and Clang in -fstrict-aliasing mode with optimizations are
>acting
>>>> as if they ran into undefined behavior, and return 4321 instead of
>the
>>>> expected 1234.  This happens in both C and C++ mode.  Intel C++ and
>Visual
>>>> C++ return the expected 1234.  All four compilers hardwire the
>result as a
>>>> constant parameter to printf rather than call test2 or modify
>memory at
>>>> runtime.
>>>>
>>>> From my reading of the C++ Standard, particularly [class.union]/5,
>>>> assignment expressions through a union member access changes the
>active
>>>> member of the union (if the union member has a trivial default
>constructor,
>>>> which it does here, being C code).  Taking the address of p2->v2
>and p1->v1
>>>> ought to be legal because those are the active members of the union
>at the
>>>> time their pointers are taken.
>>>>
>>>> Is this a well-defined program, or is there subtle undefined
>behavior
>>>> happening here?
>
>Thanks.
>
>As put in my stackoverflow answer[1], I believe this behavior is
>specified in
>the GCC-online-doc, in section `-fstrict-alisgin'[2]:
>
>    Pay special attention to code like this:
>
>    union a_union {
>      int i;
>      double d;
>    };
>    
>    int f() {
>      union a_union t;
>      t.d = 3.0;
>      return t.i;
>    }
>
>The practice of reading from a different union member than the one most
>    recently written to (called *type-punning*) is common. Even with
>   *-fstrict-aliasing*, type-punning is allowed, provided the memory is
> accessed through the union type. So, the code above works as expected.
>    See Structures unions enumerations and bit-fields implementation.
>    However, this code might not: 
>
>    int f() {
>       union a_union t;
>       int* ip;
>       t.d = 3.0;
>       ip = &t.i;
>       return *ip;
>    }

The difference is that in the original example the dynamic type of the memory 
is changed by a store to the union member via the union type. So this doesn't 
apply. 

Richard. 

> Similarly, access by taking the address, casting the resulting pointer
>  and dereferencing the result has undefined behavior, even if the cast
>    uses a union type, e.g.: 
>
>    int f() {
>      double d = 3.0;
>      return ((union a_union *) &d)->i;
>    }
>
>    The -fstrict-aliasing option is enabled at levels -O2, -O3, -Os.
>
>I think the second example above is similar to the OP's question
>(although the
>C standard might not say so... so from my perspective if the second
>example
>above is true, the OP's code is invalid.
>
>Do anyone have any comment?
>
>Yubin
>
>[1]:
>https://stackoverflow.com/questions/46205744/is-this-use-of-unions-strictly-conforming/46968235?noredirect=1#comment80930683_46968235
>[2]: https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html

Reply via email to