views:

385

answers:

4
+7  Q: 

C comma operator

Why is the expression specified inside a comma operator (such as the example below) not considered a constant expression?

For example,

int a = (10,20) ;

when given in global scope yields an error "initializer is not a constant", though both the expressions separated by a comma operator are constants (constant expressions). Why is the entire expression is not treated as a constant expression? For clarification I have read What does the ‘,’ operator do in C? and Uses of C comma operator. They have not dealt this aspect of comma operator.

A: 

gcс accepts this:

int a = (10,20) ;

int main() {
  printf("%d\n",a);
}

and prints 20. Probably it's a problem of your compiler?

egorius
My gcc (4.3.3), with no flags, doesn't accept it.
Thomas Padron-McCarthy
Which version of GCC on which platform with which flags? I tried with GCC 4.0.1 on MacOS X 10.5.8 with no flags and get the error.
Jonathan Leffler
gcc version 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)Cygwin, no flags.
egorius
@egorius try using the switch -pedantic
Ganesh Gopalasubramanian
+25  A: 

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.

paxdiablo
+1: I was just looking for this. I believe that the more in depth reason is that the comma operator introduces a sequence point.
D.Shawley
Thanks paxdiablo. The reference to rationale document is what I required to clear my doubt.
Ganesh Gopalasubramanian
+6  A: 

ISO/IEC 9899:1999 6.6/3 (Constant expressions) states that contant expressions shall not contain comma operators (unless part of a sub-expression that isn't evaluated), so (10,20) is not a constant expression by definition.

The rationale must be that because the value of the first part of the comma expression is not use it is only there for its side effects and it doesn't make sense for constant expressions to have side effects.

Charles Bailey
A: 

The compiler does not consider it as a constant expression as the variable is automatic. It is allowed to be evaluated at run-time and get a value. Try to make the variable static and you will see the same error message as the compiler will require a constant expression that time.

Michael