Section 6.6/3
, "Constant expressions", of the ISO C99 standard is the section you need. It states:
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.
In the C99 rationale document from ISO, there's this little snippet:
An integer constant expression must involve only numbers knowable at translation time, and operators with no side effects.
And, since there's no point in using the comma operator at all if you're not relying on side effects, it's useless in a constant expression.
By that, I mean there's absolutely no difference between the two code segments:
while (10, 1) { ... }
while (1) { ... }
since the 10
doesn't actually do anything. In fact,
10;
is a perfectly valid, though not very useful, C statement, something most people don't comprehend until they get to know the language better.
However, there is a difference between these two statements:
while ( 10, 1) { ... }
while (x=10, 1) { ... }
There's a side effect in the latter use of the comma operator which is to set the variable x
to 10
.
As to why they don't like side effects in constant expressions, the whole point of constant expressions is that they can be evaluated at compile-time without requiring an execution environment - ISO makes a distinction between translation (compile-time) and execution (run-time) environments.
The clue as to why ISO decided against requiring compilers to provide execution environment information (other than stuff contained in header files such as limits.h
) can be found a little later in the rationale document:
However, while implementations are certainly permitted to produce exactly the same result in translation and execution environments, requiring this was deemed to be an intolerable burden on many cross-compilers.
In other words, ISO didn't want the manufacturers of cross-compilers to be burdened with carrying an execution environment for every possible target.