【问题标题】:"Constant expressions" prior to C++11C++11 之前的“常量表达式”
【发布时间】:2014-11-19 10:06:52
【问题描述】:

constexpr 关键字是在 C++11 中引入的,因为(我认为)是“常量表达式”的相应概念。然而,这个概念隐含在 C++98/c++03 中,因为数组声明需要一个常量表达式:

// valid:
int a[sizeof(int)];
int b[3+7];
int c[13/4];
const int n = 3;
int d[n];
// invalid:
int m = 4;
int e[m];

还有其他“常量表达式”,即可以(和/或必须)在编译时计算的表达式;一个例子是模板参数。

对于 C++11 之前的版本,C++98/03 标准或其他地方是否存在以下内容?

  • 需要常量表达式的语法结构的完整列表(例如数组声明和模板实例化)
  • 管理此类常量表达式的规则(可能只是从上述列表中的项目到标准中的定义的映射)

【问题讨论】:

  • @wallyk 因为这是真的。
  • @KonradRudolph 编译器扩展的礼物,令人惊讶的是有多少 C++ 开发人员不知道这一点。
  • @wallyk 一些编译器允许在堆栈上使用可变大小的数组,但通常会发出警告。
  • @MoreAxes 通常它需要正确的标志来接收警告,对于gccclang,这将是-pedantic
  • @ShafikYaghmour 确实!当我把这些例子放在一起时,当我发现我可以在没有警告或错误的情况下编译int e[m];(使用g++)时,我一度感到困惑。

标签: c++ c++03 c++98 compile-time-constant constant-expression


【解决方案1】:

constexpr常量表达式 是相关的,因为 constexpr 告诉我们可以在 常量表达式 可以使用的地方使用变量或函数使用。这是 cppreference 告诉我们的:

constexpr 说明符声明可以计算 编译时函数或变量的值。这样的变量和 然后可以在仅编译时间常数的情况下使用函数 允许表达。

常量表达式在 C++11 之前就已经存在,并且在 C++11 之前的常量表达式的规则在 C++03 draft standard(这是最早的公共最接近 C++03)1 的草稿作为 draft C++11 standard5.19 部分 常量表达式,cppreference 对此主题有很好的总结在Constant expressions 页面中,但它面向 C++11 和 C++14,很难说出 C++11 之前的应用。

标准的 pre C++11 列出了需要常量表达式的地方,在 5.19 的第一段中,它看起来很完整:

在几个地方,C++ 要求表达式的计算结果为 整数或枚举常量:作为数组边界(8.3.4, 5.3.4),作为 case 表达式 (6.4.2),作为位域长度 (9.6),作为枚举数初始化器 (7.2),作为静态成员初始化器 (9.4.2), 并作为整数或枚举非类型模板参数 (14.3)。

1 段的其余部分说:

一个整型常量表达式只能包含 算术类型(2.13、3.9.1)、枚举器、非易失性常量 整数或枚举类型的变量或静态数据成员 用常量表达式(8.5)初始化,非类型模板 整数或枚举类型的参数,以及 sizeof 表达式。 浮动文字(2.13.3)只有在被强制转换为 整数或枚举类型。仅类型转换为整数或 可以使用枚举类型。特别是,除了 sizeof 表达式、函数、类对象、指针或引用应 不被使用,以及赋值、递增、递减、函数调用或 不得使用逗号运算符。

然后是5 更多段落,列出了进一步的要求。

在 C++11 中有一个列表,列出了可以在第 3 段中使用常量表达式的位置,但它没有明确说明它们在哪里需要。您可能必须搜索术语 constant expression 才能找到所有需要它的地方,通常会有类似于以下内容的短语:

应该是一个常量表达式

shall 是一个重要的术语,因为违反 shall 要求会使程序格式错误。

或者,您可以使用Annex A 语法摘要并搜索constant-expression,这应该涵盖语法中常量表达式 是必需的,例如:

enumerator = constant-expression

脚注:

  1. answer to Where do I find the current C or C++ standard documents? 有一份完整的标准草案列表。不幸的是,最接近公众可用的是早期的2005。早期版本需要身份验证。据我所知5.19 部分没有太大变化。

【讨论】:

  • 您链接到的标准草案是 2005 年的……这真的适用于 C++03 吗?
  • @KyleStrand 它是最早可用的公共草案标准,您可以找到所有here 可用的草案的完整列表。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-23
  • 1970-01-01
  • 1970-01-01
  • 2013-09-25
  • 1970-01-01
相关资源
最近更新 更多