在回答C11的this question on SO的过程中,我意识到在C03(以及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)];
}
QUESTION:
关于逗号运算符是否被允许用于常量表达式,或者我是否遗漏了某些内容,C 03和C 11之间是否存在差异?
作为一个奖励(非建设性)问题,我有兴趣知道为什么逗号运算符不能用在C 03中的常量表达式中 .
2 回答
是的,我相信这是C 03和C 11之间的变化 . 我相信它是基于你提到的原因而完成的 - 没有特别好的理由逗号运算符不能成为常量表达式的一部分 .
我相信C 03中的规则源于C中的规则(C90,§6.4):
至于为什么在C中的常量表达式中禁止使用逗号运算符,我只能推测 . 我的直接猜测是确保定义如下:
...将被拒绝而不是让用户误以为他只有5个元素才真正定义了
x
.没那么快 . 您还需要使用
-pedantic
(或-pedantic-errors
)让Clang和GCC严格执行C 03规则 . 有了这个,GCC主干说:和Clang Baggage 说:
正如您所注意到的,此代码是有效的C 11.但是,顶级逗号在C 11中仍然无效,因为C 11语法中的常量表达式是一种条件表达式(其中顶级逗号是不允许) . 从而:
仍然是形象不对 .