21

Recently when answering a question I realized that the comma operator is allowed in a constant expression in C++11 as long as the expression is surrounded by (), for example:

int a[ (1, 2) ] ;

Pre C++11 it is forbidden to use the comma operator in a constant expression, from the draft pre C++11 standard section 5.19 Constant expressions which says (emphasis mine):

[...]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.

Why was the comma operator not allowed in a constant expression pre C++11 and why was this restriction lifted?

Community
  • 1
  • 1
Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740

1 Answers1

20

We can find the answer to this in the std-discussion group Comma operator in constant-expression thread where Gabriel Dos Reis says:

For C++11 I proposed to allow it because the restriction appeared arbitrary and all reasons I've heard as rationale for its ban appear very unconvincing and specious to me.

and Richard Smith earlier in the thread notes some of the uses of the comma operator in a constant expression in both C++11 and C++14:

I disagree with your argument and your conclusion. In C++11, the comma operator is useful within constexpr functions, because we aren't allowed multiple statements:

template<typename T>   constexpr T my_array<T>::at(size_type n) {
  return (n < size() || throw "n too large"), (*this)[n];   }

In C++14, it's useful in essentially all of the cases where it's useful outside of constant expressions:

constexpr void do_stuff(int x[]) {
  for (int i = 0, j = 100; i != j; ++i, --j)
    x[i] = x[j];   }

More philosophically, we shouldn't ban things from constant expressions simply because we're not imaginative enough to find the cases where they're genuinely useful. Constant expressions should not be a semi-random sublanguage of C++, missing random features, to the extent that we can avoid that. These days, top-level commas are prohibited mostly because constant-expressions tend to occur in contexts where a comma would mean something else.

Note it was argued that his C++11 example is not correct since the the expression containing the comma operator should be in () but his example gives the essence of the argument. The argument would be based on the grammar from section 5.19 Constant expressions:

constant-expression:
   conditional-expression

we can not get to comma operator from a conditional-expression but we can get to primary-expression which gets us to ( expression ) and we can then get to the comma operator from expression.

T.C. points out that this may not be the case since the relevant section seems vague on this point.

Community
  • 1
  • 1
Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
  • I would probably explain also why the `()` is required in C++11 (it's the grammar, which requires a *conditional-expression*). – T.C. Dec 05 '14 at 22:55
  • @T.C. Fair point, I am commuting and won't be able to do a real edit for a bit but I address that in the [link I provide](http://stackoverflow.com/a/27297736/1708801) in the question above. – Shafik Yaghmour Dec 05 '14 at 23:06
  • 1
    I'm also not quite sure if Richard Smith's C++11 example is incorrect. An invocation of a `constexpr` function is a *conditional-expression* and hence fits the grammar, so the question is whether the invocation, "when substituted by function invocation substitution", produces a constant expression, and the spec in [dcl.constexpr]/p5 is wonderfully vague about the exact expression produced by *function invocation substitution*. – T.C. Dec 05 '14 at 23:12
  • @T.C. Hmmm, interesting question. He did not disagree with that assessment during the discussion but that does not mean it is correct. I would have to think about that. – Shafik Yaghmour Dec 05 '14 at 23:16
  • Whether his example `constexpr` function was correctly written or missing a pair of parentheses, I don't see how that affects Richard's point that allowing the comma is useful for `constexpr` functions. – T.C. Dec 06 '14 at 03:01
  • So I'm not sure what "Although I would argue Richard's point does not make much sense otherwise." is about? – T.C. Dec 06 '14 at 03:10
  • @T.C. I see how that was not clear now, I removed that sentence. – Shafik Yaghmour Dec 06 '14 at 17:55