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?
begin static initialization
i = 0
ar[0] = 0
ar[1] = 0
i ............. constant initialization is not done, because f() is not a constant
expression
ar[0] = 42 .... constant initialization is done, because 42 is a constant literal
integral type. Even if your interpreation is that ar[0] should be
dynamically initialized, based on 3.6.2 note 3, ar[0] can be initialized
either statically or dynamically. Its implementation dependent, unless
the standard explicitly requires array element initialization to be
an all or nothing operation.
ar[1] ......... constant initialization is not done, because i is not a constant
expression
end static initialization
begin dynamic initialization
nonlocal variables with static storage duration have ordered dynamic initialization
i = f() = 1 ... f() does not abort because a[0] == 42 and a[1] == 0.
a[1] = 1
enjoy,
Karen