在回答C ++ 11 this question on SO的过程中,我意识到在C ++ 03(以及C)中,在常量中明确禁止使用逗号运算符 - 表达
关于常量表达式的C ++ 03标准的第5.19 / 1段说:
[...]特别是,除了sizeof表达式,函数,类对象,指针或 不得使用引用,并且赋值,递增,递减,函数调用或逗号运算符应 不得使用。
然而,在C ++ 11中,提到逗号运算符的最后一部分似乎已经消失了。虽然C ++ 11标准的第5.19 / 2段明确规定赋值,递增,递减和非constexpr
函数调用表达式不应作为常量表达式的子表达式出现,似乎不再禁止使用逗号运算符。
例如,以下程序在GCC 4.7.2和Clang 3.3上用std=c++11
编译好(除了编译器警告说逗号运算符没有效果,x
和arr
变量未使用):
int main()
{
constexpr int x = (0, 42);
int arr[(0, 42)];
}
但是,必须要说的是,即使是以下程序也可以使用-std=c++03
选项(在Clang和GCC上)编译好,这显然不正确,给出上述引用C ++ 03标准:
int main()
{
int arr[(0, 42)];
}
问题:
C ++ 03和C ++ 11之间是否存在逗号运算符是否被允许用于常量表达式,或者我是否遗漏了某些东西?
作为一个奖励(非建设性)问题,我有兴趣知道为什么逗号运算符不能用在C ++ 03中的常量表达式中。
答案 0 :(得分:14)
是的,我相信这是C ++ 03和C ++ 11之间的变化。我认为这完全是出于你提到的原因 - 没有特别好的理由,逗号运算符不能成为常量表达式的一部分。
我认为C ++ 03中的规则源于C中的规则(C90,§6.4):
常量表达式不应包含赋值,递增,递减,函数调用或逗号运算符,除非它们包含在 sizeof 运算符的操作数中。
为什么在C中的常量表达式中禁止使用逗号运算符,我只能推测。我的直接猜测是确保定义如下:
int x[2, 5];
...会被拒绝,而不是让用户错误地认为他已定义了一个2x5元素数组,当(如果允许逗号运算符)时,他确实只定义了x
5个元素。
答案 1 :(得分:3)
但是,必须要说的是,即使是以下程序也可以使用-std = c ++ 03选项(在Clang和GCC上都可以编译),这显然是不正确的,因为上面引用了C ++ 03标准
没那么快。您还需要使用-pedantic
(或-pedantic-errors
)来让Clang和GCC严格执行C ++ 03规则。有了这个,GCC主干说:
<stdin>:1:16: error: array bound is not an integer constant before ‘]’ token
和Clang主干说:
<stdin>:1:19: error: variable length arrays are a C99 feature [-Werror,-Wvla-extension]
void f() { int arr[(0, 42)]; }
^
正如您所知,此代码是有效的C ++ 11。但是,顶级逗号在C ++ 11中仍然无效,因为C ++ 11语法中的常量表达式是一种条件-expression (不允许使用顶级逗号)。因此:
int arr[0, 42];
仍然是不合格的。