int i = 1 || (2, 3);
int main() {
return 0;
}
At issue is this text in 6.6 paragraph 3:
Constant expressions shall not contain assignment, increment, decrement, function-call, or comma operators, except when they are contained within a subexpression that is not evaluated.The not evaluated part is at least meant to apply to operands of sizeof; the attached footnote says as much. However, it also (inadvertently?) applies in other cases. 6.5.14 paragraph 4, on the
||
operator, says, in part:
If the first operand compares unequal to 0, the second operand is not evaluated.
Therefore, a literal reading suggests that the comma operator in the above example is valid because it appears in a subexpression that is not evaluated.
In the C89 standard, the 6.6 wording said "... except when
they are contained within the operand of a sizeof operator".
Presumably, this wording was changed in C99 to accommodate sizeof
applied to a variable length array, which does require evaluation
and should not be allowed in a constant expression. However,
because the phrase "not evaluated" is also used for the
unevaluated operands of the &&
and
||
operators, the valid forms of constant
expressions may have been inadvertently expanded by the
change.
Further evidence of the intent of the change is provided by the associated footnote, which changed from "The operand of a sizeof operator is not evaluated, ..." in C89 to "The operand of a sizeof operator is usually not evaluated" in C99. Given that the only case in which the operand of a sizeof is evaluated is a variable length array, it seems clear that the change was intended to impose an additional constraint on constant expressions, not remove one.
Suggested technical corrigendum:
In 6.6p3, replace..., except when they are contained within a subexpression that is not evaluated.with
..., except when they are contained within the operand of a sizeof operator of which the operand is not evaluated.