[cfe-dev] question about initializing multiple members of unions

Matthew Curtis mcurtis at codeaurora.org
Mon Sep 16 07:11:21 PDT 2013


Richard, Doug,

Do either of you have an recommendation here?

Eli recommends GCC's behavior, while Philip Reames and Gao would both 
prefer the alternate behavior below (same as a series of assignments).

Thanks,
Matthew Curtis


On 9/11/2013 8:10 AM, Matthew Curtis wrote:
> I'm investigating an assert in clang compiling the following code:
>
>   typedef union {
>     struct {
>       int zero;
>       int one;
>       int two;
>       int three;
>     } a;
>     int b[4];
>   } my_agg_t;
>
>   my_agg_t agg_instance =
>   {
>     .b[0] = 0,
>     .a.one = 1,
>     .b[2] = 2,
>     .a.three = 3,
>   };
>
> I'm a little uncertain as to what this *should* do.
>
> GCC (4.4.3) produces this assembly:
>
>   agg_instance:
>     .zero 12
>     .long 3
>
> I had thought that maybe it should produce
>
>   agg_instance:
>     .long 0
>     .long 1
>     .long 2
>     .long 3
>
> Which is the effect that most implementations would have if you
> were to execute the analogous assignments:
>
>   agg_instance.b[0] = 0,
>   agg_instance.a.one = 1,
>   agg_instance.b[2] = 2,
>   agg_instance.a.three = 3,
>
> Experimenting with various orderings of the designated initializers
> leads me to believe that whenever the member of the union being
> initialized changes, GCC discards any previous member initializations.
>
> For clang, this ordering
>
>   my_agg_t agg_instance =
>   {
>     .a.one = 1,
>     .b[0] = 0,
>     .a.three = 3,
>     .b[2] = 2,
>   };
>
> does not assert and produces
>
>   agg_instance:
>     .long 0
>     .long 1
>     .long 2
>     .long 3
>
> Though after stepping through some of the code I think this may be
> accidental.
>
> Reading sections 6.7.2.1 and 6.7.8 of the spec, it's not clear to me
> exactly what the behavior should be, though I could see how GCC's
> behavior would be considered compliant.
>
> Thoughts?
> Matthew Curtis
>
> ----------------------------------------------------------------------
> BTW, Here are the portions of the C99 spec[0] that I thought were
> relevant
>
> 6.7.2.1 Structure and union specifiers
>
> 14 [...] The value of at most one of the members can be stored in a
> union object at any time. [...]
>
> 6.7.8 Initialization
>
> 17 [...] a designation causes the following initializer to begin
> initialization of the subobject described by the designator.
> Initialization then continues forward in order, beginning with the
> next subobject after that described by the designator. 128)
>
> 19 The initialization shall occur in initializer list order, each
> initializer provided for a particular subobject overriding any
> previously listed initializer for the same subobject; 130) [...]
>
> 128) After a union member is initialized, the next object is not the
> next member of the union; instead, it is the next subobject of an
> object containing the union.
>
> 130) Any initializer for the subobject which is overridden and so not
> used to initialize that subobject might not be evaluated at all.
>
> [0] http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev


-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation




More information about the cfe-dev mailing list