简体   繁体   中英

G++ vs Clang : inconsistent behavior for constexpr and const

Consider the following code:

constexpr const int A = 42;

const int &B = A;
static_assert(&A == &B, "Bug");

constexpr const int &C = B;
static_assert(&A == &C, "Bug");

int main() { return 0; }

It is perfectly accepted by clang version 3.3, whereas g++ (SUSE Linux) 4.8.1 20130909 [gcc-4_8-branch revision 202388 refuses it with:

bug2.cpp:5:1: error: non-constant condition for static assertion
 static_assert(&A == &B, "Bug");
 ^
bug2.cpp:5:1: error: the value of ‘B’ is not usable in a constant expression
bug2.cpp:2:12: note: ‘B’ was not declared ‘constexpr’
 const int &B = A;
            ^

It seems to me that GCC is correct (whereas I certainly would prefer clang behavior). Trying to read the standard I realized that I'm not enough of a language lawyer to decide. Can anyone confirm that?

the value of 'B' is not usable in a constant expression is incorrect. You are not performing an lvalue-to-rvalue conversion on B, which is the usual meaning of "value;" you are only taking its address. The only relevant constant-expression rule forbids:

an id-expression that refers to a variable or data member of reference type unless the reference has a preceding initialization, initialized with a constant expression;

However B does have a preceding initialization to a reference constant expression.

A reference constant expression is an lvalue core constant expression that designates an object with static storage duration or a function.

In this case, B 's initializer is A , which is as constant as you can get. A and B statically refer to the same object.

So, this is a GCC bug.

Without being a language lawyer, you cannot use a reference as a constant expression in general, only values (if there are exceptions please correct me). In this sense, the closest valid to your code would be:

constexpr int A = 42;
constexpr int B = A;

static_assert(A == B, "Bug");

However, in my case, both Clang 3.3 and GCC 4.8.1 give errors on your code as expected.

EDIT Apparently my knowledge is still a bit narrow, sorry. There are probably exceptions depending on linkage, for instance the code is accepted ( live ) if the statements are global, outside main() .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM