6

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.

Wake up Brazil
  • 3,421
  • 12
  • 19
  • 3
    This isn't the latest draft (n3797 / github repo), and *core constant expression* is defined in [expr.const]/2: "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: [...]" – dyp Dec 20 '13 at 01:05
  • AFAIK, `double` is a literal type, so b) should apply. – dyp Dec 20 '13 at 01:08
  • Hmm maybe you just misunderstood [expr.const]/2? It defines a *core constant expression* in terms of a *conditional-expression*, not the other way round. *conditional-expression* is defined in [expr.cond]. – dyp Dec 20 '13 at 01:12
  • @DyP "This isn't the latest draft". See `latest publicly available draft` here (http://www.open-std.org/jtc1/sc22/wg21/). 5.19p2 defines a `conditional-expression` not a `core constant expression`. – Wake up Brazil Dec 20 '13 at 01:13
  • See new comment. It's the other way round: 5.19p2 defines *core constant expression*. The WG21 page is probably outdated, see http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/ and http://isocpp.org/ (which already refers to N3797) – dyp Dec 20 '13 at 01:14
  • I have a feeling that the question depends on [whether initialization requires lvalue-to-rvalue conversion](https://stackoverflow.com/questions/14935722/does-initialization-entail-lvalue-to-rvalue-conversion-is-int-x-x-ub). – Kerrek SB Dec 20 '13 at 01:18
  • @DyP "double is a literal type" I agree with that. Tks. – Wake up Brazil Dec 20 '13 at 01:58

1 Answers1

8

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;
Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
  • English is not my native tongue. But reading the assertion above I just can't see that as a definition of a `core constant expression`. Could you clarify? – Wake up Brazil Dec 20 '13 at 01:21
  • The answer is correct, that paragraph defines a core constant expression. Consider a similar construction for defining an adult: "a human is an adult unless then are under 18". It defines a core constant expression as a subset of conditional expressions. – Jonathan Wakely Dec 20 '13 at 01:31
  • @JonathanWakely "It defines a core constant expression as a subset of conditional expressions". If this is so, how does this definition apply to the expression `constexpr double y = x;` in the snippet, given that `x` clearly is not a conditional expression? – Wake up Brazil Dec 20 '13 at 01:40
  • 2
    `x` is a *conditional-expression*, as is any expression whose top-level operator is not an assignment or comma. A *conditional-expression* needn't have a `?:` conditional operator. Look at the grammar. – Keith Thompson Dec 20 '13 at 01:45
  • @KeithThompson I can't see anything in the grammar that tells me that `x` is a conditional-expression. – Wake up Brazil Dec 20 '13 at 01:55
  • @WakeupBrazil: 5.16: *conditional-expression* -> *logical-or-expression*. 5.15: *logical-or-expression* -> *logical-and-expression*. [skipping several steps] 5.2 *postfix-expression* -> *primary-expression*. 5.1 *primary-expression* -> *id-expression* -> *unqualified-id* -> *identifier*. – Keith Thompson Dec 20 '13 at 02:00
  • @KeithThompson How come `x`is a conditional expression? See 5.16 p1 `Conditional expressions group right-to-left. The first expression is contextually converted to bool (Clause 4)`. How come `x` is converted to bool in the expression `constexpr double y = x;`??? – Wake up Brazil Dec 20 '13 at 02:15
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/43556/discussion-between-keith-thompson-and-wake-up-brazil) – Keith Thompson Dec 20 '13 at 02:31