<div dir="ltr">On Wed, Sep 25, 2013 at 8:12 PM, Karen Shaeffer <span dir="ltr"><<a href="mailto:shaeffer@neuralscape.com" target="_blank">shaeffer@neuralscape.com</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">

<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><div>On Wed, Sep 25, 2013 at 03:08:06PM -0700, Eli Friedman wrote:<br>


> On Wed, Sep 25, 2013 at 3:02 PM, Karen Shaeffer <<a href="mailto:shaeffer@neuralscape.com" target="_blank">shaeffer@neuralscape.com</a>>wrote:<br>
><br>
> > On Wed, Sep 25, 2013 at 02:40:37PM -0700, Eli Friedman wrote:<br>
> > > On Wed, Sep 25, 2013 at 4:49 AM, Karthik Bhat <<br>
> > <a href="mailto:blitz.opensource@gmail.com" target="_blank">blitz.opensource@gmail.com</a>>wrote:<br>
> > ><br>
> > > > Hi All,<br>
> > > > I was going through a gcc TC for C++11. The test case is as follows -<br>
> > > ><br>
> > > > // { dg-options -std=c++0x }<br>
> > > > // { dg-do run }<br>
> > > ><br>
> > > > extern "C" void abort ();<br>
> > > > extern int ar[2];<br>
> > > ><br>
> > > > int f()<br>
> > > > {<br>
> > > >   int k = 0;<br>
> > > >   if (ar[0] != 42 || ar[1] != 0)<br>
> > > >     abort();<br>
> > > >   return 1;<br>
> > > > }<br>
> > > ><br>
> > > > int i = f();<br>
> > > ><br>
> > > > int ar[2] = {42,i};<br>
> > > ><br>
> > > > int main()<br>
> > > > {<br>
> > > >   return 0;<br>
> > > > }<br>
> > > ><br>
> > > > During dynamic initialization of i in function f() the value of ar[0]<br>
> > is 0<br>
> > > > in case of clang were as in case of gcc it is 42.<br>
> > > ><br>
> > > > As per standard(section 3.6.2) all global values should initially be<br>
> > zero<br>
> > > > initialized followed by const initialized if possible before dynamic<br>
> > > > initialization takes place.<br>
> > > > Hence as per standard the const initialization of int ar[2] = {42,i};<br>
> > > > should fail as i is not a const here( which seems to be happening in<br>
> > > > clang). Hence ar[0],ar[1] is still zero initialized because of which<br>
> > during<br>
> > > > dynamic initialization in f() ar[0]  is 0 which seems to be the correct<br>
> > > > behavior.<br>
> > > ><br>
> > > > Can i conclude here that clang is behaving correctly and the tc is<br>
> > wrong?<br>
> > > > or am i missing something which this gcc tc wanted to capture?<br>
> > > ><br>
> > ><br>
> > > As far as I can tell, your analysis is correct.<br>
> > ><br>
> > > -Eli<br>
> ><br>
> > Hi,<br>
> > But isn't function f a constexpr? It doesn't modify anything and always<br>
> > returns 1.<br>
> ><br>
> ><br>
> It doesn't matter what the implementation of "f" is; "f()" is still not a<br>
> constant expression.  Please read [basic.start.init] and [expr.const] in<br>
> the C++ standard.<br>
><br>
> -Eli<br>
<br>
</div></div>Hi Eli,<br>
OK. I agree. f() is not a constexpr because the body of the function is not a<br>
return statement. There are other problems, but that is moot.<br>
<br>
Based on my reading of the C++11 standard at 3.6.2 note 3, this g++ test case<br>
appears to be fully compliant with the standard. I am referring to the static<br>
initialization of ar[0] to 42. see notes below.<br>
<br>
Temporary breakpoint 1, main (argc=1, argv=0x7fffffffe5c8) at constexpr.cpp:385<br>
385     {<br>
(gdb) print i<br>
$1 = 1<br>
(gdb) print ar<br>
$2 = {42, 1}<br>
<br>
When i is initialized by f(), ar[0] = 42 and ar[1] = 0. My interpretation is<br>
that g++ is initializing ar[0] and ar[1] as individual variables, with respect to<br>
the fact ar[1] has an initializer that is not a constant expression. Unless the<br>
standard explicitly prohibits the static initialization of ar[0], because of some<br>
all or nothing rule pertaining to the static initialization of the elements of an<br>
array and noting i is not a constant expression, I believe the g++ test case is<br>
valid code.<br>
<br>
My interpretation doesn't necessarily mean clang has a bug here. But the standard<br>
must explicitly forbid static initialization of ar[0], because the initializer of<br>
ar[1] is not a constant expression, or at the least define it as implementation<br>
dependent, or it would be a bug in clang. Where is this clarified in the standard?<br>
Specifically, where in the standard does it require nonlocal static initialization<br>
of elements of an array to be an all or nothing operation?<br><br></blockquote><div>[basic.start.init]p2:  Variables with ordered initialization defined within a single translation unit shall be initialized in the order of their definitions in the translation unit.</div>
</div><div class="gmail_quote"><br></div><div class="gmail_quote">There isn't really any room to interpret that any way other than what clang is doing.<br><div><br></div></div>-Eli</div></div>