[cfe-dev] Query regarding global value initialization standard

Karen Shaeffer shaeffer at neuralscape.com
Fri Sep 27 11:55:31 PDT 2013


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

Hi,
I took a few minutes to look a little further. And the stl library containers all abort()
when used in the test case scheme. It appears g++ makes the distinction for this test case
for c-style arrays only. stl containers all adhere to the all or nothing nonlocal static
initialization constraint, using dynamic initialization consistent with clang.

I haven't had time yet to check if clang is aggressively using 3.6.2 note 3 exception that
permits nonlocal static initialization in specific cases where note 2 prohibits it, but I
am confident clang does. Its important in the context of concurrency, avoiding the per
translation unit nonlocal dynamic initialization ordering issues, available since c++11.

enjoy,
Karen
-- 
Karen Shaeffer                 Be aware: If you see an obstacle in your path,
Neuralscape Services           that obstacle is your path.        Zen proverb



More information about the cfe-dev mailing list