1

I read many questions here but couldn't find my answer, considering following statements:

int x;
x = 1, 2, 3;

this gives x value of 1 however as there are other values separated by , why the rest is discarded? shouldn't it be 3? or is it because of precedency of = over ,?

Then if I write

int x = 1, 2, 3;

now it doesn't compile. what's the real difference between the two?

5
  • You can verify your assumption regarding operator precedence by simply putting 1,2,3 in brackets: (1,2,3) Commented Aug 17, 2022 at 9:47
  • If something does not compiler you should show the exact error message. Commented Aug 17, 2022 at 9:47
  • x=1, is a syntactically correct expression. 2, is another, 3; is another... Now, does the difference begin to make sense? Commented Aug 17, 2022 at 9:53
  • This printf("x=%d\n", x), 42; perhaps shows why there is a difference between x = 1, 2, 3; and x = (1, 2, 3);. Commented Aug 17, 2022 at 9:55
  • 1
    First one is a sequence of three sub-expressions executed one after another with the last one being the final result of the combined expression. You might want to play around a bit: x = 1, y = 2, z = 3 or z = (x = 1, y = 2) or z = (x = 1, 2). Commented Aug 17, 2022 at 9:56

2 Answers 2

2

You already found out that = has higher precedence. Therefore that first code is similar to

(x = 1),2, 3;

That means you have an assignment and you have 2 values combined by comma operator.

The assignment is evaluated to 1 (besides actually assigning a value to x) and you get an expression like this: 1,2,3; which is evaluated but ignored.

In your second snippet things are different.

int x =1, 2, 3;

Again the precedence is same.

If you add brackets int x = (1,2,3); you will get value 3 as you expected.

Without the brackets, the compiler expects the name of the next variable that you want to define here. 2 and 3 are no valid identifiers to define variables and therefore the compiler complains.

Sign up to request clarification or add additional context in comments.

Comments

1

x = 1, 2, 3;

Due to precedence, this is interpreted as (x = 1), 2, 3;.

int x = 1, 2, 3;

In an expression statement such as x = 1, 2, 3;, you can use any expression. However, in a declaration, an initializer can only be an assignment-expression (or a list of initializers inside { and }).

The way the formal C grammar is written, the top-level operator of an expression can be any of the C operators, but the top-level operator of an assignment-expression can be any of the C operators except ,. Therefore, if a , is seen when parsing the top level of an initializer, it cannot be part of the initializer, so it ends the initializer. (A , can appears inside parentheses in an initializer.)

Here are some details about how this works. The formal grammar says:

  • An expression is either expression , assignment-expression or is an assignment-expression.
  • An assignment-expression is either unary-expression assignment-operator assignment-expression or is a conditional-expression.
  • A conditional-expression is either logical-OR-expression ? expression : conditional-expression or is a logical-OR-expression.
  • This chain continues through all the operators in C.

So, when a C compiler is looking for an expression, it notionally goes through each of these choices, accepting either a comma operator or an assignment operator or a conditional operator, and so on. When it is looking for an assignment-expression (in a declaration), it starts with the second choice, an assignment operator, notionally skipping over the comma as a possibility.

1 Comment

TYSM for much broader explanation, can you please give a short example for each list items you kindly mentioned? That would be much helpful.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.