5

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

人们还可以发现,这里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;
}

我特别考虑表达式中的lvalue to rvalue implicit conversionof 变量,上面提到的第 (10) 项中的 (a)、(b) 和 (c) 中的任何一个子句都没有涵盖该变量。xconstexpr double y = x;

谢谢您的帮助。

4

1 回答 1

7

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

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

[列表省略]

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

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

仅在本国际标准的一小部分中使用的术语在其使用处进行了定义,并在其定义处用斜体表示。

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

至于示例代码:

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

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

这意味着在没有诊断的情况下接受上述代码的编译器是不合格的(即,有缺陷的)。(除非我遗漏了什么,这是完全可能的。)

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

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

constexpr double x = 2.;
constexpr double y = x;
于 2013-12-20T01:13:19.627 回答