-2

In c ,

main()   {
 int a = (1,2,3,4);
  printf("%d",a); 
}

yields an output of

4

This is because comma(,)operator has a right to left precedence . But

main()   {
int a = {1,2,3,4};
 printf("%d",a);
}

yields an output

1

anyone pls explain the logic behind this. Thanks

gsamaras
  • 71,951
  • 46
  • 188
  • 305
wahid_abdul
  • 156
  • 2
  • 9
  • What does `gcc -Wall` tell you? – Yunnosch Jun 26 '17 at 14:04
  • 1
    I think that this is a [constraint violation](http://port70.net/~nsz/c/c11/n1570.html#6.7.9p2), and hence undefined behavior. – ad absurdum Jun 26 '17 at 14:05
  • None of this looks remotely standard, nor correct as of 2017, or the past 30 years. – DeiDei Jun 26 '17 at 14:05
  • It is actually perfectly fine C. Nearly identical duplicate: https://stackoverflow.com/questions/35266987/int-nums-5-2-1-4-causes-a-segmentation-fault – Lundin Jun 26 '17 at 14:14
  • @Lundin (replaced comment) -- I see it's trying to do this to a pointer, but this question doesn't discuss whether this is allowed. See my answer, is my interpretation of §6.7.9 -- 2 wrong? –  Jun 26 '17 at 14:21

3 Answers3

5

{1,2,3,4} is the syntax for an initializer, used to initialize something that has more than one value, like an array or a struct. So the commas inside it are not operators, they are just part of the initializer syntax.

When initializing, C uses the values from the initializer from the left. As you initialize a single scalar variable, only one element is needed.

Your compiler is supposed to tell you that this code doesn't make sense:

x.c:2:12: warning: excess elements in scalar initializer
 int a = {1,2,3,4};
            ^

I should add that this code violates a constraint of the standard, see C11 draft N1570, § 6.7.9 -- 2:

No initializer shall attempt to provide a value for an object not contained within the entity being initialized.

This requires the compiler to emit a diagnostic when compiling such broken code.

From the same paragraph is the following rule (number 17):

Each brace-enclosed initializer list has an associated current object. When no designations are present, subobjects of the current object are initialized in order according to the type of the current object: array elements in increasing subscript order, structure members in declaration order, and the first named member of a union.1

So your compiler decides to do the "next closest" thing to the standard and just use the first value you provide.

2

That's an initializer (usually used for arrays), but you are not using it wisely, didn't your compiler tell you?

Georgioss-MacBook-Pro:~ gsamaras$ gcc -Wall main.c 
main.c:2:13: warning: excess elements in scalar initializer
 int a = {1,2,3,4};
            ^

The precedence here is from left to right, and since you have only one element to initialize, one element is chosen from the initializer (that is 1 in this case).

gsamaras
  • 71,951
  • 46
  • 188
  • 305
1

The curly braces mean initialization of the variable, mostly useful for arrays.

In your case, compiling with gcc yields:

test.c:6:12: warning: excess elements in scalar initializer
 int a = {1,2,3,4};
            ^

(same for 3 & 4)

Means that only value 1 is useful for your case (it's a scalar)

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219