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.
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.
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.
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.
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;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With