What is a core constant expression in the C++11 Standard?

1.2k views Asked by At

There are 11 references to the expression core constant expression in the latest draft of the C++11 Standard (N3690), and none of them defines what this entity is.

One can also find that the expression core constant expression is pretty well defined here , basically in the same terms that the Standard uses to define the expression conditional-expression.

Therefore, I would like to get some input on this issue, which seems to me, to be wrong in the Standard.

Now, assuming the definition in cppreference is correct I would also like to know why the following snippet compiles in Coliru and in Ideone, despite item (10) in the alluded definition?

#include <iostream>

int main()
{
    const double x = 2.;
    constexpr double y = x;
    std::cout << y << std::endl;
}

I'm specifically thinking in terms of the lvalue to rvalue implicit conversion of variable x in the expression constexpr double y = x;, which is not covered by any of the clauses (a), (b) and (c) in item (10) referred above.

Thanks for the help.

1

There are 1 answers

8
Keith Thompson On BEST ANSWER

N3690 does define the term "core constant expression in 5.19p2 [expr.const]:

A conditional-expression e is a core constant expression unless the evaluation of e, following the rules of the abstract machine (1.9), would evaluate one of the following expressions:

[list omitted]

The released ISO C++ 2011 standard defines it in the same section.

As for whether that's actually a definition, see also section 1.3, paragraph 3:

Terms that are used only in a small portion of this International Standard are defined where they are used and italicized where they are defined.

The standard also uses italics for syntactic categories such as conditional-expression, but "core constant expression" is a defined term, not a syntactic category (it's subtle, but you can tell by the use of spaces rather than hyphens to separate the words).

As for the sample code:

const double x = 2.;
constexpr double y = x;

my reading of the standard is that this is invalid, because x is not a core constant expression. It would be valid if x and y were of some integer or enumeration type, but there's no such permission for floating-point. An lvalue-to-rvalue conversion (converting the name of the object x to its value 2.0) is not permitted in a core constant expression unless it meets one of three listed criteria (see C11 5.19, 9th bullet, three sub-bullets).

This implies that the compilers that accept the above code without a diagnostic are non-conforming (i.e., buggy). (Unless I'm missing something, which is entirely possible.)

Which implies that http://en.cppreference.com/w/cpp/language/constant_expression is wrong. It says that a core constant expression may contain an lvalue-to-rvalue conversion of an lvalue that "has literal type and refers to an object defined with a constant expression (or to its subobject)". The actual standard has a stronger requirement: the object must be defined with constexpr. (Perhaps cppreference.com was based on an earlier draft?)

So the sample code could be made valid by changing it to:

constexpr double x = 2.;
constexpr double y = x;