<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Word 14 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:"MS Mincho";
        panose-1:2 2 6 9 4 2 5 8 3 4;}
@font-face
        {font-family:"MS Mincho";
        panose-1:2 2 6 9 4 2 5 8 3 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:Tahoma;
        panose-1:2 11 6 4 3 5 4 4 2 4;}
@font-face
        {font-family:"\@MS Mincho";
        panose-1:2 2 6 9 4 2 5 8 3 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:"Times New Roman","serif";}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph
        {mso-style-priority:34;
        margin-top:0in;
        margin-right:0in;
        margin-bottom:0in;
        margin-left:.5in;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:"Times New Roman","serif";}
span.EmailStyle17
        {mso-style-type:personal-reply;
        font-family:"Calibri","sans-serif";
        color:#1F497D;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri","sans-serif";
        mso-fareast-language:JA;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal">Hi Richard,<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">According to c11 6.7.9p19, “<span style="mso-fareast-language:JA">The initialization shall occur in initializer list order, each initializer provided for a<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="mso-fareast-language:JA">particular subobject overriding any previously listed initializer for the same subobject; all sub-objects that are<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="mso-fareast-language:JA">not initialized explicitly shall be initialized implicitly the same as objects that have static storage duration.”<o:p></o:p></span></p>
<p class="MsoNormal"><span style="mso-fareast-language:JA"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="mso-fareast-language:JA">In Matthew’s example, <o:p>
</o:p></span></p>
<p class="MsoNormal">  my_agg_t agg_instance =<br>
  {<br>
    .b[0] = 0,<br>
    .a.one = 1,<br>
    .b[2] = 2,<br>
    .a.three = 3,<br>
  };<o:p></o:p></p>
<p class="MsoNormal"><span style="mso-fareast-language:JA"><o:p> </o:p></span></p>
<p class="MsoNormal">If you think that “.a.three = 3” overrides “.b[2] = 2”, “.a.one = 1” and “.b[0] = 0”, then .b[0] and .b[2] should take the value<o:p></o:p></p>
<p class="MsoNormal">zero as if they were initialized as static objects, giving the end result {0, 0, 0, 3}.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">If you think that “.a.three = 3” does not override “.b[2] = 2” and “.b[0] = 0”, then .b[0] and .b[2] will be<o:p></o:p></p>
<p class="MsoNormal">initialized to 0 and 2 respectively, giving the end result {0, 1, 2, 3}.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">I do not think {unspecified, unspecified, unspecified, 3} is a viable interpretation.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">- Gao.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<div style="border:none;border-left:solid blue 1.5pt;padding:0in 0in 0in 4.0pt">
<div>
<div style="border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal"><b><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif"">From:</span></b><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif""> cfe-dev-bounces@cs.uiuc.edu [mailto:cfe-dev-bounces@cs.uiuc.edu]
<b>On Behalf Of </b>Richard Smith<br>
<b>Sent:</b> Monday, September 16, 2013 11:05 AM<br>
<b>To:</b> Matthew Curtis<br>
<b>Cc:</b> cfe-dev@cs.uiuc.edu Developers<br>
<b>Subject:</b> Re: [cfe-dev] question about initializing multiple members of unions<o:p></o:p></span></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<p class="MsoNormal">On Mon, Sep 16, 2013 at 7:11 AM, Matthew Curtis <<a href="mailto:mcurtis@codeaurora.org" target="_blank">mcurtis@codeaurora.org</a>> wrote:<o:p></o:p></p>
<div>
<div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<p class="MsoNormal">Richard, Doug,<br>
<br>
Do either of you have an recommendation here?<br>
<br>
Eli recommends GCC's behavior, while Philip Reames and Gao would both prefer the alternate behavior below (same as a series of assignments).<o:p></o:p></p>
</blockquote>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Can you explain how treating the designated initializers as a sequence of assignments could give the object the value {0, 1, 2, 3}?<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Per C11 <a href="http://6.2.6.1/7">6.2.6.1/7</a>, "When a value is stored in a member of an object of union type, the bytes of the object representation that do not correspond to that member but do correspond to other members take unspecified
 values." This doesn't really say what happens if you store a value in a *subobject* of a member of an object of union type, but the natural extension would seem to be that the bytes of the object representation that do not correspond to that subobject take
 unspecified values.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Footnote 95 allows reading the contents of an inactive member of a union (by reinterpreting the value as the other type), but that only applies to reads through an inactive union member, not to stores.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">So under Eli's approach, we get {0, 0, 0, 3}, and under the other approach, it can be argued that we get {unspecified, unspecified, unspecified, 3}.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">I'm reasonably convinced that this is a hole in the C standard -- it doesn't specify what to do in this case -- and Eli's approach seems completely reasonable to me. Plus it has the benefit of being compatible with at least two other major
 compilers (g++ and EDG), and doesn't require us to invent a new representation for initializer lists.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<p class="MsoNormal">Thanks,<br>
Matthew Curtis<o:p></o:p></p>
<div>
<div>
<p class="MsoNormal"><br>
<br>
<br>
On 9/11/2013 8:10 AM, Matthew Curtis wrote:<o:p></o:p></p>
<p class="MsoNormal">I'm investigating an assert in clang compiling the following code:<br>
<br>
  typedef union {<br>
    struct {<br>
      int zero;<br>
      int one;<br>
      int two;<br>
      int three;<br>
    } a;<br>
    int b[4];<br>
  } my_agg_t;<br>
<br>
  my_agg_t agg_instance =<br>
  {<br>
    .b[0] = 0,<br>
    .a.one = 1,<br>
    .b[2] = 2,<br>
    .a.three = 3,<br>
  };<br>
<br>
I'm a little uncertain as to what this *should* do.<br>
<br>
GCC (4.4.3) produces this assembly:<br>
<br>
  agg_instance:<br>
    .zero 12<br>
    .long 3<br>
<br>
I had thought that maybe it should produce<br>
<br>
  agg_instance:<br>
    .long 0<br>
    .long 1<br>
    .long 2<br>
    .long 3<br>
<br>
Which is the effect that most implementations would have if you<br>
were to execute the analogous assignments:<br>
<br>
  agg_instance.b[0] = 0,<br>
  agg_instance.a.one = 1,<br>
  agg_instance.b[2] = 2,<br>
  agg_instance.a.three = 3,<br>
<br>
Experimenting with various orderings of the designated initializers<br>
leads me to believe that whenever the member of the union being<br>
initialized changes, GCC discards any previous member initializations.<br>
<br>
For clang, this ordering<br>
<br>
  my_agg_t agg_instance =<br>
  {<br>
    .a.one = 1,<br>
    .b[0] = 0,<br>
    .a.three = 3,<br>
    .b[2] = 2,<br>
  };<br>
<br>
does not assert and produces<br>
<br>
  agg_instance:<br>
    .long 0<br>
    .long 1<br>
    .long 2<br>
    .long 3<br>
<br>
Though after stepping through some of the code I think this may be<br>
accidental.<br>
<br>
Reading sections 6.7.2.1 and 6.7.8 of the spec, it's not clear to me<br>
exactly what the behavior should be, though I could see how GCC's<br>
behavior would be considered compliant.<br>
<br>
Thoughts?<br>
Matthew Curtis<br>
<br>
----------------------------------------------------------------------<br>
BTW, Here are the portions of the C99 spec[0] that I thought were<br>
relevant<br>
<br>
6.7.2.1 Structure and union specifiers<br>
<br>
14 [...] The value of at most one of the members can be stored in a<br>
union object at any time. [...]<br>
<br>
6.7.8 Initialization<br>
<br>
17 [...] a designation causes the following initializer to begin<br>
initialization of the subobject described by the designator.<br>
Initialization then continues forward in order, beginning with the<br>
next subobject after that described by the designator. 128)<br>
<br>
19 The initialization shall occur in initializer list order, each<br>
initializer provided for a particular subobject overriding any<br>
previously listed initializer for the same subobject; 130) [...]<br>
<br>
128) After a union member is initialized, the next object is not the<br>
next member of the union; instead, it is the next subobject of an<br>
object containing the union.<br>
<br>
130) Any initializer for the subobject which is overridden and so not<br>
used to initialize that subobject might not be evaluated at all.<br>
<br>
[0] <a href="http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf" target="_blank">
http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf</a><br>
<br>
_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@cs.uiuc.edu" target="_blank">cfe-dev@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev</a><o:p></o:p></p>
<p class="MsoNormal" style="margin-bottom:12.0pt"><o:p> </o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal" style="margin-bottom:12.0pt">-- <br>
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation<o:p></o:p></p>
</div>
</div>
</blockquote>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
</div>
</div>
</div>
</body>
</html>