简体   繁体   中英

Is the comma operator allowed in a constant-expression in C++11?

In the process of answering this question on SO for C++11, I realized that in C++03 (as well as in C) the use of the comma operator is explicitly forbidden in a constant-expression .

Paragraph 5.19/1 of the C++03 Standard on constant expressions says:

[...] In particular, except in sizeof expressions, functions, class objects, pointers, or references shall not be used, and assignment, increment, decrement, function-call, or comma operators shall not be used .

In C++11, however, that last part mentioning the comma operator seems to be vanished. And while paragraph 5.19/2 of the C++11 Standard clearly specifies that assignment, increment, decrement, and non- constexpr function call expressions shall not appear as sub-expressions of a constant-expression , the usage of the comma operator does not seem to be forbidden anymore.

For instance, the following program compiles fine on GCC 4.7.2 and Clang 3.3 with std=c++11 (apart from compiler warnings saying the comma operator has no effect and the x and arr variables are unused):

int main()
{
    constexpr int x = (0, 42);
    int arr[(0, 42)];
}

However, it must be said that even the following program compiles fine with the -std=c++03 option (both on Clang and GCC), which is clearly not correct, given the above quote from the C++03 Standard:

int main()
{
    int arr[(0, 42)];
}

QUESTION:

Is there a difference between C++03 and C++11 as to whether or not the comma operator is allowed in a constant expression, or am I missing something?

As a bonus (non-constructive) question, I would be interested in knowing why the comma operator cannot be used in a constant expression in C++03.

  1. Yes, I believe this is a change between C++03 and C++11. I believe it was done for roughly the reason to which you allude -- that there's no particularly good reason a comma operator can't be part of a constant expression.

  2. I believe the rule in C++03 originated from the rule in C (C90, §6.4):

Constant expressions shall not contain assignment, increment, decrement, function-call, or comma operators, except when they are contained within the operand of a sizeof operator.

As to why the comma operator was prohibited in constant expressions in C, I can only speculate. My immediate guess would be to assure that a definition like:

int x[2, 5];

...would be rejected instead of leaving the user with the mistaken belief that he'd defined a 2x5 element array, when (if a comma operator were allowed there) he'd really defined x with only 5 elements.

However, it must be said that even the following program compiles fine with the -std=c++03 option (both on Clang and GCC), which is clearly not correct, given the above quote from the C++03 Standard

Not so fast. You need to also use -pedantic (or -pedantic-errors ) to get Clang and GCC to strictly enforce the C++03 rules. With that, GCC trunk says:

<stdin>:1:16: error: array bound is not an integer constant before ‘]’ token

and Clang trunk says:

<stdin>:1:19: error: variable length arrays are a C99 feature [-Werror,-Wvla-extension]
void f() { int arr[(0, 42)]; }
                  ^

As you note, this code is valid C++11. However, top-level commas are still not valid in C++11, because a constant-expression in the C++11 grammar is a kind of conditional-expression (where a top-level comma is not permitted). Thus:

int arr[0, 42];

is still ill-formed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM