在回答this question on SO for C++11的过程中,我意识到在C++03 (以及C)中,常量表达式中明确禁止使用逗号运算符。
关于常数表达式的C++03标准第5.19/1段说:
..。特别是,除大量表达式外,不应使用类对象、指针或引用,而赋值、增量、减量、函数调用或逗号运算符不应使用。
然而,在C++11中,最后提到逗号运算符的部分似乎消失了。虽然C++11标准第5.19/2段明确规定,赋值、增量、递减和非constexpr函数调用表达式不应显示为常数表达式的子表达式,但逗号运算符的使用似乎不再被禁止。
例如,以下程序可以使用std=c++11编译GCC 4.7.2和Clang 3.3 (除了编译器警告说逗号运算符没有作用,以及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中的常量表达式中使用。
发布于 2013-05-16 02:54:10
常数表达式不应包含赋值、增量、递减、函数调用或逗号运算符,除非它们包含在大小的运算符的操作数中。
至于为什么C中的常量表达式禁止逗号运算符,我只能推测。我的直接猜测是确保这样的定义:
int x[5, 2];...would被拒绝。如果允许的话,这可能会导致程序员错误地认为他定义了一个5x2元素数组(总共有10个元素),而当(如果允许一个逗号操作符)时,他实际上只用2个元素定义了x (实际上完全忽略了5 )。
至于为什么C++委员会认为这是一个比C委员会更可接受的风险,我想这可以归结为一个相当简单的情况:C提供了几乎没有替代的方法,因此数组被大量使用。另一方面,C++提供了std::array和std::vector,留下了很少有理由使用"raw“数组的情况,因此出现问题的可能性要小得多。
发布于 2013-07-14 00:31:24
但是,必须指出的是,即使下面的程序也可以使用-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克莱尔的后备箱上写着:
<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语法中的常量表达式是一种条件表达式(不允许顶级逗号)。因此:
int arr[0, 42];仍然是畸形的。
https://stackoverflow.com/questions/16576933
复制相似问题