38
#include<stdio.h> 
int main(void) {
   int a;
   a = (1, 2), 3; 
   printf("%d", a);
   return 0;
}

output: 2
Can any one explain how output is 2?

L. F.
  • 19,445
  • 8
  • 48
  • 82
Kr Arjun
  • 249
  • 3
  • 9
  • 2
    You might be able to figure it out yourself by also examining `a = 1,2,3;` and `a = (1,2,3);`. – molbdnilo Sep 12 '17 at 13:11
  • What exactly is your question? Why it is not 3 or 1? Or generally how comma operator works? – Gerhardh Sep 12 '17 at 13:17
  • 5
    Can you explain what was your expectation when you wrote the code? It's not like putting statements and expression together, the code should be meaningful. What is that you try to achieve? – Sourav Ghosh Sep 12 '17 at 13:21
  • 6
    @Olaf To answer the question it is not necessary to know, what the OP expects. Just explain the mechanisms which lead to the result "2" (if you want to take the effort and answer it) – Ctx Sep 12 '17 at 13:30
  • 1
    The output is 2 because you print the contents of the variable `a` which holds a value of 2. (You should probably phrase your question better, don't you think?) – StoryTeller - Unslander Monica Sep 12 '17 at 13:33
  • What did _you_ expect to be contained in `a`? – Jabberwocky Sep 12 '17 at 13:38
  • 4
    @Olaf The question is clearly not about debugging, yet it is on-topic – Ctx Sep 12 '17 at 13:39
  • 12
    @Olaf The OP is curious, why C behaves that way. The operator precedence is a catch here, and I do not think, that this particular case is described in most good C books. This is neither debugging nor "too broad", but trying to understand how this (non-trivial) construct works. I disagree, that this is a spoon-feeding question. – Ctx Sep 12 '17 at 13:45
  • 9
    @Olaf I disagree. Even when expecting an outcome you can wonder "how" or "why". I have not seen this case before and found it interesting. Agree with Ctx here. – Hans Petter Taugbøl Kragset Sep 12 '17 at 13:46
  • @HansPetterTaugbølKragset: You might want to take the [tour] again and read [ask]. We are not a guessing site; speculation about the motivations of a poster is not what we do here. Questions are to be helpful not only for the asker, but a wider audience. I (and most likely other C seniors) also have not seen this before; simply because it does not make sense. But we know the basics about preceedence and how the comma-operator works. That's C 101! – too honest for this site Sep 12 '17 at 14:43
  • However it works, or doesn't work, that does not change the fact that anyone writing such code should be imprisoned overnight and then brutally guillotined in the morning. Such code is a very bad example, and is of negative use to future visitors/users:( – Martin James Sep 12 '17 at 14:51
  • 1
    The [Wikipedia article](https://en.wikipedia.org/wiki/Comma_operator) on the comma operator answers this question as well, a quick Google would have answered it before posting. – CodeMonkey1313 Sep 12 '17 at 14:57
  • 2
    @CodeMonkey1313: I still think the question is a good one because even people who are familiar with a language can get tripped up while reading such code. Such constructs shouldn't appear in "straight-line" code, of course, but may cause trouble when using macros that don't include all the necessary parentheses. – supercat Sep 12 '17 at 15:16
  • Related: https://stackoverflow.com/questions/35066654/precedence-of-comma-operator – Dimitris Fasarakis Hilliard Sep 12 '17 at 15:36
  • This question seems too broad / unclear in its current state (a single line of code can still consist of multiple unrelated parts, which should be split into multiple questions). If you don't know what the comma operator does, your question should focus on that. If you know what the comma operator does, but still don't understand how you end up with 2 (instead of something else, presumably), you should state as much (although if the misunderstanding is operator precedence, that's probably not a question that will be useful for any future visitors). – Bernhard Barker Sep 12 '17 at 15:46
  • I advise you to increase your compilers warning-level if it does not say anything relevant. – Deduplicator Sep 12 '17 at 17:41
  • @Ctx "*Just explain the mechanisms which lead to the result "2"*" But that might not answer the OP's underlying question. The OP's confusion might be that he was expecting "2" to be interpreted as an ASCII character. Maybe the "," in the `printf` was confusing him. There's nothing wrong with assuming the OP meant what it is most likely they meant. But it's perfectly reasonable to ask for clarification as well so you can be confident that you're answering *precisely* what it is the OP is asking about. Both requests for clarification seem reasonable to me given the question's vagueness. – David Schwartz Sep 12 '17 at 19:06

3 Answers3

63

Can any one explain how output is 2?

Because the precedence of the assignment operator (=) is higher than the comma operator (,).

Therefore, the statement:

a = (1, 2), 3;

is equivalent to:

(a = (1, 2)), 3;

and the expression (1, 2) evaluates to 2.

JFMR
  • 23,265
  • 4
  • 52
  • 76
  • 33
    @Olaf Oh, yes, it does answer the question: It means that `a` is assigned the value of the expression `(1, 2)`, which is `2`. The `, 3` is irrelevant to the assignment. – cmaster - reinstate monica Sep 12 '17 at 13:23
  • 1
    @cmaster: I don't see any indication OP assume `3`. He could as well expect `1`. Which has a different reason. – too honest for this site Sep 12 '17 at 13:24
  • @cmaster Why the 3 is irrelevant to the assignment ? I don't really understand :c – Gam Sep 12 '17 at 13:25
  • 1
    Well, sometimes the answer should find the right balance between guiding and spoon-feeding... – Eugene Sh. Sep 12 '17 at 13:25
  • 1
    @Gam: We are not a tutoring site! Learning C by trial&error or obscure YT videos or blogs does not work, most of their authors don't really know the language well and they only concentrate on particular aspects. Get a good textbook about **modern** C (C99 at least, better C11) and work through the lessons. – too honest for this site Sep 12 '17 at 13:26
  • 4
    @Gam Re-read the expression `(a = (1, 2)), 3`: The subexpression that performs the assignment does not even contain a `3`. Does that clear things up? – cmaster - reinstate monica Sep 12 '17 at 13:27
  • 3
    @cmaster Oh yeah sorry I get it now ! The variable is taking the value 2 (the 1 is useless here), then the expression "3" is evaluated but it does not matter it does nothing – Gam Sep 12 '17 at 13:31
  • You are aware that `(a = (1, 2)), 3;` does actually not compile. – Jabberwocky Sep 12 '17 at 13:43
  • @MichaelWalz It does compile http://rextester.com/SQCNS79126 – JFMR Sep 12 '17 at 13:46
  • @眠りネロクoh yes, sorry, and it actually compiles pretty everywhere except [here](https://www.ideone.com/adBzHJ) – Jabberwocky Sep 12 '17 at 13:56
29

Can any one explain how output is 2?

In the statement

a = (1, 2), 3;   

, used is a comma operator. Due to higher operator precedence of = operator than that of , operator, the expression operand (1, 2) will bind to = as

(a = (1, 2)), 3;  

In case of comma operator, the left operand of a comma operator is evaluated to a void expression, then the right operand is evaluated and the result has the value and type of the right operand.

There are two comma operators here. For the first comma operator in the expression (1, 2), 1 will be evaluated to void expression and then 2 will be evaluated and will be assigned to a.
Now side effect to a has been taken place and therefore the right operand of second comma operator 3 will be evaluated and the value of the expression (a = (1, 2)), 3 will be 3.

haccks
  • 104,019
  • 25
  • 176
  • 264
4

the result of:

a = x, y     =>     x

a = (i, j)   =>     j

therefore, if we have:

x = (1 , 2)

a = (1 , 2) , 3     =>     2

As said here:

The comma operator separates expressions (which have value) in a way analogous to how the semicolon terminates statements, and sequences of expressions are enclosed in parentheses analogously to how sequences of statements are enclosed in braces: (a, b, c) is a sequence of expressions, separated by commas, which evaluates to the last expression c while {a; b; c;} is a sequence of statements, and does not evaluate to any value. A comma can only occur between two expressions – commas separate expressions – unlike the semicolon, which occurs at the end of a (non-block) statement – semicolons terminate statements.

The comma operator has the lowest precedence of any C operator, and acts as a sequence point. In a combination of commas and semicolons, semicolons have lower precedence than commas, as semicolons separate statements but commas occur within statements, which accords with their use as ordinary punctuation: a, b; c, d is grouped as (a, b); (c, d) because these are two separate statements.

I hope this answers your question.

Rui Silva
  • 413
  • 1
  • 5
  • 12