<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Mar 17, 2015 at 3:55 PM, Daniel Berlin <span dir="ltr"><<a href="mailto:dberlin@dberlin.org" target="_blank">dberlin@dberlin.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote"><span class="">On Tue, Mar 17, 2015 at 3:32 PM, Jeroen Dobbelaere <span dir="ltr"><<a href="mailto:jeroen.dobbelaere@gmail.com" target="_blank">jeroen.dobbelaere@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Mar 17, 2015 at 11:15 PM, Daniel Berlin <span dir="ltr"><<a href="mailto:dberlin@dberlin.org" target="_blank">dberlin@dberlin.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir="ltr"><br><div class="gmail_extra">[..]<span><div><div style="font-family:arial,helvetica,sans-serif;font-size:10pt;color:rgb(0,0,0)">I don't understand what this means. How should they do that? </div></div><div class="gmail_quote"><div><div><div><br></div></div></div><div>So, his point was the arrays have no connections to the union. This is not the only case this occurs in.</div><div><br></div><div>Let's take the canonical example:</div><div><br></div><div><br></div><div>For example</div><div><br></div><div>union foo {</div><div>int a;</div><div>float b;</div><div>};</div><div><br></div><div>int ihateunions(int *a, float *b)</div><div>{</div><div><do a thing with a and b></div><div>}</div><div><br></div><div>int passtounion()</div><div>{</div><div>union foo bar;</div><div>ihateunions(&bar.a, &bar.b);</div><div><br></div><div>}</div><div><br></div><div>Inside ihateunions, you will have no idea that a and b are connected to unions.</div><div><br></div><div>Let's say this example is easy, i mean, they are both at offset 0, so they can alias, right?</div><div><br></div></div></span></div></div></blockquote><div><br></div><div>My understanding is that if you access members of a union in this way,  the compiler is allowed<br></div><div>to assume that a and b do not alias.<br></div></div></div></div></blockquote><div><br></div><div><br></div></span><div>In theory, the last time i remember, you weren't allow to set one member of a union and read another.</div><div>But uh, that's not real user code :)</div><div><br></div><div>(and IIRC, it does not say anything real)</div><span class=""><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><br></div><div>If you access a member (or nested member) of a union, starting from the union itself, then it depends if the other type is also accessible through the union.<br><br><br></div><div>So:<br><br></div><div>int foo(union foo* a, float* b, int* c) {<br></div><div>  a->a=1;<br></div><div>  *b=2;<br></div><div>  // compiler must assume a->a and *b can alias<br></div><div>  // compiler must not assume *b and *c alias (access not through union)<br></div><div>}<br><br></div><div>(Also see section 3.10 of the c++03 standard;</div></div></div></div></blockquote><div><br></div><div><br></div></span><div>This, IMHO, does not say what you seem to think it does :)</div><div><br></div><div>For C++03,  3.10 only includes the word "union" here: "If a program attempts to access the stored value of an object through an lvalue of other than one of the following
types the behavior is undefined: </div><div><br></div><div>— the dynamic type of the object, </div><div>— a cv-qualified version of the dynamic type of the object, </div><div>— a type that is the signed or unsigned type corresponding to the dynamic type of the object,</div><div> — a type that is the signed or unsigned type corresponding to a cv-qualified version of the dynamic type of
the object, </div><div>— an aggregate or union type that includes one of the aforementioned types among its members (including,
recursively, a member of a subaggregate or contained union),</div><div> — a type that is a (possibly cv-qualified) base class type of the dynamic type of the object,</div><div> — a char or unsigned char type."<br><div><br><br></div><div>C++ standard experts, at least on the GCC side, did not view this as saying "all accesses must have an explicit union access", but that "It must be part of a union type", but about whether you try to access it through a union that doesn't have the right actual types in it.</div></div><div><br></div><div>The type of those objects is right the type of the object. There is, IMHO,  nothing illegal about those accesses.</div><div><br></div></div></div></div></blockquote><div><br></div><div>BTW, the example I gave is trivially transformable into one on structs:<br><br></div><div><div><br class="">struct foo {</div><div>int a;</div><div>float b;</div><div>};</div><div><br></div><div>int ihatestructs(int *a, float *b)</div><div>{</div><div><do a thing with a and b></div><div>}</div><div><br></div><div>int passtostruct()</div><div>{</div><div>struct foo bar;</div><div>ihatestructs(&bar.a, &bar.b);</div><div>}</div></div><div><br></div><div>Given 3.10 says literally nothing different about accesses through unions and accesses through aggregates (they are even in the same sentence), i don't see how you can reason your way to say that unions give a different result than strucfts in the above case.</div><div><br></div><div>That is, strictly on a TBAA basis, i don't see how you believe the standard allows different answers.</div><div>(Practically, i know why we are okay with them :P)</div><div><br></div><div>Now, TBAA combined with other info, i can see.  This is because in the above example, with TBAA you can say "TBAA says *a and *b in ihatestructs can't alias unless they were accessed through an structure that contained both". So far so good (though note, this alone gives you *nothing* about the above unless you are guaranteed to  have the whole program in front of you).  Struct rules tell us that a and b must not be at the same offset, and memory layout rules tell us that objects at different offsets can not alias.  So, combined, we have "TBAA says *a and *b can't alias unless they are a structure, and if they were in a structure, they can't alias because they aren't at the same offset".  These two things combined tell you *a and *b can't alias.</div><div>But either one alone does not.</div><div><br></div><div>This is the problems with unions. You don't get the second part easily, because they may in fact, be at the same offset.<br></div><div><br></div><div><br></div><div> <br></div></div></div></div>