什么是C++ 11标准中的核心常量表达式?

Wak*_*zil 4 c++ language-lawyer constant-expression c++11

core constant expression在C++ 11标准(N3690)的最新草案中有11个对表达式的引用,它们都没有定义这个实体是什么.

人们还可以发现这里的表达式core constant expression定义很好,基本上与标准用于定义表达式的术语相同.conditional-expression

因此,我想在这个问题上获得一些意见,在我看来,这个问题在标准中是错误的.

现在,假设cppreference中的定义是正确的,我还想知道为什么下面的代码片段在ColiruIdeone中编译,尽管在提到的定义中有第(10)项?

#include <iostream>

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

我特别考虑表达式中lvalue to rvalue implicit conversion的变量,而上述第(10)项中的任何条款(a),(b)和(c)都没有涵盖这一点.xconstexpr double y = x;

谢谢您的帮助.

Kei*_*son 5

N3690 确实定义了"5.19p2 [expr.const]中的核心常量表达式":

条件表达式 Ë是一个核心常量表达式除非的评价Ë,以下抽象机(1.9),将评估下面的表达式中的一个的规则:

[列表省略]

已发布的ISO C++ 2011标准在同一部分中定义了它.

至于这是否真的是一个定义,另见第1.3节第3段:

仅在本国际标准的一小部分中使用的术语在使用它们时定义,并在定义它们时定义斜体.

该标准还使用斜体来表示句法类别,例如条件表达式,但"核心常量表达式"是一个定义的术语,而不是句法类别(它是微妙的,但你可以通过使用空格而不是连字符来区分单词) .

至于示例代码:

const double x = 2.;
constexpr double y = x;
Run Code Online (Sandbox Code Playgroud)

我的标准的解读是,这是无效的,因为x不是一个核心的常量表达式.这将是,如果有效x,并y是一些整数或枚举类型,但有浮点没有这样的权限.除非符合三个列出的标准之一,否则不允许在核心常量表达式中进行左值到右值的转换(将对象的名称转换x为其值2.0)(请参阅C11 5.19,第9个子弹,3个子项目符号).

这意味着在没有诊断的情况下接受上述代码的编译器是不符合的(即,错误).(除非我遗漏了一些东西,这完全有可能.)

这意味着http://en.cppreference.com/w/cpp/language/constant_expression是错误的.它表示核心常量表达式可能包含左值的左值到右值的转换,"左值"具有文字类型并且引用用常量表达式(或其子对象)定义的对象".实际标准有更强的要求:必须定义对象constexpr.(也许cppreference.com是基于早期的草案?)

因此,通过将示例代码更改为:

constexpr double x = 2.;
constexpr double y = x;
Run Code Online (Sandbox Code Playgroud)

  • `x` 是一个*条件表达式*,就像任何顶级运算符不是赋值或逗号的表达式一样。*条件表达式* 不需要有 `?:` 条件运算符。看看语法。 (2认同)