[cfe-dev] Query regarding global value initialization standard

Karthik Bhat blitz.opensource at gmail.com
Wed Sep 25 21:19:27 PDT 2013


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!


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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20130926/034e0544/attachment.html>


More information about the cfe-dev mailing list