C comma operator

2019-01-02 21:26发布

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.

4条回答
与君花间醉酒
2楼-- · 2019-01-02 21:38

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.

查看更多
刘海飞了
3楼-- · 2019-01-02 21:41

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.

查看更多
时光乱了年华
4楼-- · 2019-01-02 21:51

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.

查看更多
其实,你不懂
5楼-- · 2019-01-02 21:52

gcс accepts this:

int a = (10,20) ;

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

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

查看更多
登录 后发表回答