This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [std-discussion] Is this union aliasing code well-defined?


On Fri, Oct 27, 2017 at 3:00 PM, Yubin Ruan <ablacktshirt@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?
>>
>> Melissa
>>
>> --
>>
>> ---
>> You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
>> To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+unsubscribe@isocpp.org.
>> To post to this group, send email to std-discussion@isocpp.org.
>> Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]