33

The following code has me confused

int a=2,b=5,c;
c=a+++b;
printf("%d,%d,%d",a,b,c);

I expected the output to be 3,5,8, mainly because a++ means 2 +1 which equals 3, and 3 + 5 equals 8, so I expected 3,5,8. It turns out that the result is 3,5,7. Can someone explain why this is the case?

user595985
  • 1,543
  • 4
  • 29
  • 55
  • 9
    `a++` most certainly does not mean `2+1`. :) – jalf Sep 20 '11 at 12:27
  • 2
    these are just exercises in a book, but they've got me thinking. I keep getting them wrong!, so its not production code or anything – user595985 Sep 20 '11 at 12:31
  • 1
    Unless you are writing a C++ parser/compiler, you should never have to write/think about expressions like `a+++b`, which someone reading the code later could easily interpret as `a + (++b)` which would evaluate to 8. Spaces and parenthesis are free and will make everyone's life easier in this case. – dr jimbob Sep 20 '11 at 15:01
  • 8
    tired of people asking this: http://stackoverflow.com/questions/5677271 http://stackoverflow.com/questions/5341202 http://stackoverflow.com/questions/5752910 http://stackoverflow.com/questions/5649354 – BlueRaja - Danny Pflughoeft Sep 20 '11 at 18:14
  • @BlueRaja-DannyPflughoeft in essence this is not really a maximal munch question it is basically a misunderstanding about how post-increment works which is basically off-topic by today's standards. – Shafik Yaghmour Nov 18 '14 at 15:19

9 Answers9

96

It's parsed as c = a++ + b, and a++ means post-increment, i.e. increment after taking the value of a to compute a + b == 2 + 5.

Please, never write code like this.

Fred Foo
  • 355,277
  • 75
  • 744
  • 836
  • 2
    And which is the rule that states it is parsed as `a++ + b`, and not as `a + ++b`? The tokenizer is greedy? – Blagovest Buyukliev Sep 20 '11 at 12:27
  • 1
    I assume it must be strictly left-associative. – Patrick87 Sep 20 '11 at 12:29
  • @BlagovestBuyukliev: check your local C grammar or [this one](http://www.lysator.liu.se/c/ANSI-C-grammar-y.html). – Fred Foo Sep 20 '11 at 12:29
  • i guess the compiler is reading left to write and gives to ++ precedence with respect to a single + – Stefano Sep 20 '11 at 12:30
  • 40
    The reason is that the lexer of C and C++, try to match the biggest string they can when they see something. That's the reason you don't see `var` as three tokens `v`, `a` and `r`. Or why you see `>=` as one token and not `>` and `=`. Also the same reason why you see a `>>` token in `vector>` causing parse errors. Therefore, when the lexer sees the first plus, it tries the next character, it sees that it can match both characters as a `++`, then continues on to see the next `+`. Hence, the parser sees `a ++ + b` – Shahbaz Sep 20 '11 at 12:33
  • @BlagovestBuyukliev: While the C++ standard does not specify a precedence table, one can be inferred from the grammar that is specifed in the standard. Post-increment has a higher precedence than does pre-increment. – David Hammen Sep 20 '11 at 13:20
  • Thanks everyone, the question basically comes from a book that's designed to test what one understands. So I've found it extremely useful in teasing out what i do know and highlight what i do not. The examples or NOT for any kind of production, merely to expand one's understanding. Again Thanks – user595985 Sep 20 '11 at 14:00
  • 7
    @Blagovest Buyukliev: For C, The rule is 6.4 para 4: "If the input stream has been parsed into preprocessing tokens up to a given character, the next preprocessing token is the longest sequence of characters that could constitute a preprocessing token..." – John Bode Sep 20 '11 at 14:36
  • Has anybody else noticed this answer gets the correct result for the wrong reasons? It is most certainly not parsed as `a+b` but as `(a++)+b` it just so happens that the post increment `a++` returns the value of `a` *before* incrementing, i.e. 2. – Dan Sep 20 '11 at 14:52
  • `(a++) + b` is the same as `a++ + b` by C's precedence rules and the value of `(a++)` within an expression where `a` occurs exactly once is the value of `a` before the increment. – Fred Foo Sep 20 '11 at 15:20
  • yes but in your answer you state "increment after computing `a+b`" which is to say the code is equivalent to `a+b;a=a+1` which it isn't, it is more like `f(a)+b` where `f(int& a){int tmp=a;a=a+1;return tmp;}` – Dan Sep 20 '11 at 16:59
  • ... answer is incomplete you forgot: "Please throw that book away and get a better one" – Trevor Boyd Smith Sep 20 '11 at 17:32
  • 10
    Your point that the tokenization is "a ++ + b" is correct but your claim that the increment happens *after* a + b is computed is in error. The C and C++ languages do not specify *at what time* the increment is computed relative to the addition. It would be perfectly legal for this to be computed as "temp = a++", and then "temp + b", computing the addition of "a + b" after the increment. Remember, the *values* of expressions and the *sequence of moments in time at which they are observed to have those values* are very different analyses to make. – Eric Lippert Sep 20 '11 at 18:34
  • @EricLippert, I see what you mean. I tried to keep the answer simple, but added a bit on this anyway. – Fred Foo Sep 20 '11 at 22:10
40

Maximal Munch Rule applies to such expression, according to which, the expression is parsed as:

c = a++ + b;

That is, a is post-incremented (a++) and so the current value of a (before post-increment) is taken for + operation with b.

Nawaz
  • 353,942
  • 115
  • 666
  • 851
6

a++ is post incrementing, i.e. the expression takes the value of a and then adds 1.
c = ++a + b would do what you expect.

David
  • 2,226
  • 32
  • 39
2

This is an example of bad programming style.

It is quite unreadable, however it post increments a so it sums the current value of a to b and afterwards increments a!

dcharles
  • 4,822
  • 2
  • 32
  • 29
Stefano
  • 3,981
  • 8
  • 36
  • 66
1

a++ gets evaluated after the expression.

c = ++a + b; would give you what you thought.

jrok
  • 54,456
  • 9
  • 109
  • 141
1

The post increment operator, a++, changes tge value of a after the value of a is evaluated in the expression. Since the original value of a is 2, that's what's used to compute c; the value of a is changed to reflect the new value after the ++ is evaluated.

Patrick87
  • 27,682
  • 3
  • 38
  • 73
1

a++ + b ..it gives the result 7 and after the expression value of a is update to 3 because of the post increment operator

Aman Agarwal
  • 727
  • 6
  • 15
1

According to Longest Match rule it is parsed as a++ + +b during lexical analysis phase of compiler. Hence the resultant output.

Vineet G
  • 175
  • 1
  • 1
  • 8
0

Here c= a+++b; means c= (a++) +b; i.e post increment. In a++, changes will occur in the next step in which it is printing a, b and c. In ++a, i.e prefix-increment the changes will occur in the same step and it will give an output of 8.