Question

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.

Was it helpful?

Solution

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;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top