Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 808
Wake up Brazil Avatar asked Dec 20 '13 00:12

Wake up Brazil


People also ask

What is a constant expression in C?

A constant expression gets evaluated at compile time, not run time, and can be used in any place that a constant can be used. The constant expression must evaluate to a constant that is in the range of representable values for that type.

What does constant expression mean?

A constant expression is an expression that can be evaluated at compile time. Constants of integral or enumerated type are required in several different situations, such as array bounds, enumerator values, and case labels. Null pointer constants are a special case of integral constants.

What is expression in C++ with example?

An expression can consist of one or more operands, zero or more operators to compute a value. Every expression produces some value which is assigned to the variable with the help of an assignment operator. Examples of C++ expression: (a+b) - c. (x/y) -z.


1 Answers

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;
like image 92
Keith Thompson Avatar answered Sep 21 '22 09:09

Keith Thompson