C++11之前的"常量表达式"

15
``` 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 标准或其他地方是否存在以下内容?

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

4
因为这是真实的。 - Konrad Rudolph
1
@KonradRudolph 给予编译器扩展的礼物,令人惊讶的是有多少 C++ 开发者不知道这一点。 - Shafik Yaghmour
2
@wallyk 有些编译器允许在堆栈上使用可变大小的数组,但通常会发出警告。 - More Axes
1
@MoreAxes 通常需要适当的标志来接收警告,对于 gccclang 来说,这将是 -pedantic - Shafik Yaghmour
1
@ShafikYaghmour 的确!当我编写这些示例时,我曾经困惑过一会儿,因为我发现我可以使用 g++ 编译 int e[m]; 而没有警告或错误。 - Kyle Strand
显示剩余4条评论
1个回答

13

constexprconstant expressions 之间有关联,constexpr 告诉我们一个变量或函数可以用在只允许使用 constant expression 的地方。这是来自 cppreference 的说法:

constexpr 声明在编译期间可以计算出函数或变量的值。这样的变量和函数可以用在只有编译期常量表达式允许的地方。

Constant expressions 在 C++11 之前已经存在,规定了在 C++11 之前的 constant expressions 的规则都在 C++03 草案标准 中被涵盖(这是最接近 C++03 的可用的最早公共草案版本1,与 C++11 草案标准 中的第 5.19Constant expressions 相同,cppreference 中的 Constant expressions 页中有关于这个主题的良好摘要,但它是针对 C++11 和 C++14 的,很难知道哪些适用于 C++11 之前。

C++11 之前的标准列出了需要使用 constant expression 的地方,在第一个段落中的 5.19 中,看起来很完整:

在几个地方,C++ 需要求表达式求值为整数或枚举常量:作为数组界限(8.3.4、5.3.4)、作为 case 表达式(6.4.2)、作为位域长度(9.6)、作为枚举器初始值设定项(7.2)、作为静态成员初始化程序(9.4.2)以及作为整数或枚举非类型模板参数(14.3)。

剩下的第一段说:

整数常量表达式只能包含算术类型(2.13、3.9.1)的字面量、枚举器、非易失 const 变量或使用整数或枚举类型的常量表达式进行初始化的静态数据成员(8.5)、整数或枚举类型的非类型模板参数和 sizeof 表达式。浮点字面量(2.13.3)只能出现在它们被强制转换为整数或枚举类型时。只能使用到整数或枚举类型的类型转换。特别地,在 sizeof 表达式中除外,不得使用函数、类对象、指针或引用,并且不得使用赋值、递增、递减、函数调用或逗号运算符。

并跟随着另外 5 个段落,列出了更多的要求。

在 C++11 中,常量表达式可以使用的位置在第三段中列出,但它没有澄清它们所需的位置。您可能需要搜索术语 constant expression 才能找到其所需的所有位置,通常会有类似以下短语的词组:enumerator = constant-expression


注:

  1. 这个回答:我在哪里可以找到当前的C或C++标准文档?列出了所有的草案标准。不幸的是,最接近公众可获得的版本是早期的2005年版本。早期的版本需要身份验证才能获得。据我所知,第5.19部分没有太大变化。

你链接的草案标准是2005年的...那真的是针对C++03吗? - Kyle Strand
@KyleStrand 这是最早的公开草案标准,您可以在此找到所有可用的草案完整列表:https://dev59.com/wnVD5IYBdhLWcg3wHnyd。 - Shafik Yaghmour

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接