[cfe-dev] Query regarding global value initialization standard

Karen Shaeffer shaeffer at neuralscape.com
Fri Sep 27 12:07:03 PDT 2013


On Thu, Sep 26, 2013 at 09:49:27AM +0530, Karthik Bhat wrote:
> Also i think standard section 3.6.2 point 2 mentions as -
> 
> Constant initialization is performed:
> — *if each full-expression (including implicit conversions) that appears in
> the initializer of a reference with*
> *static or thread storage duration is a constant expression* (5.19) and the
> reference is bound to an lvalue
> designating an object with static storage duration or to a temporary (see
> 12.2);
> 
> since i here is not const expression the point each full-expression that
> appears in the initializer fails in this tc and hence a[0] need not be
> const initialized to 42.
> Am i right?
> 
> Thanks!

Hi Karthik,

I believe you cannot use a rule that must be satisfied in 3.6.2 note 2 to invalidate
the use of note 3 exception. If you get to note 3, it is a precondition that you already
failed to satisfy the conditions set forth in note 2. Note 3 presents a different set
of conditions, that if satisfied, give the implementation the option to ignore the failure
in note 2 requirements.

While you point to a statement that is clearly related to the all or nothing initialization
of containers or classes, that all or nothing rule is associated with the objects themselves
outside of the scope of 3.6.2 note 2. I believe that is what is needed to invalidate the use
of 3.6.2 note 3 exception - a general rule associated with the objects outside the scope of
note 2.

I wanted to thank you for sharing the test case. Interesting and informative.

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

> 
> 
> On Thu, Sep 26, 2013 at 9:40 AM, Eli Friedman <eli.friedman at gmail.com>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
> >



More information about the cfe-dev mailing list