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

时间:2013-12-20 00:59:10

标签: c++ c++11 language-lawyer constant-expression

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

我们也可以发现表达式core constant expression定义得非常明确here,基本上与标准用于定义表达式conditional-expression的术语相同。

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

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

#include <iostream>

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

我特别考虑表达式lvalue to rvalue implicit conversion中变量x的{​​{1}},其中没有任何条款(a),(b)和(c)在上文提到的第(10)项中。

感谢您的帮助。

1 个答案:

答案 0 :(得分:5)

N3690 确定在5.19p2 [expr.const]中定义“核心常量表达式”:

  

条件表达式 e 核心常量表达式,除非   评估 e ,遵循抽象机的规则(1.9),   将评估以下表达式之一:

     

[list ignored]

已发布的ISO C ++ 2011标准在同一部分中对其进行了定义。

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

  

仅在本国际的一小部分内使用的条款   标准是在使用它们的地方定义的,并且在它们所在的位置使用斜体   定义

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

示例代码:

const double x = 2.;
constexpr double y = x;

我对该标准的解读是这是无效的,因为x 核心常量表达式。如果xy具有某种整数或枚举类型,那么它是有效的,但是没有浮点数的这种权限。 核心常量表达式中不允许进行左值到右值的转换(将对象的名称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;