-1

I wrote the following C program to find the output for a+++b

#include<stdio.h>
int main()
{
    int a=5, b=2; 
    printf("%d",a+++b);
}

And I'm getting the output as 7 which is correct according to lexical analysis.

Apart from that I wrote a separate program to find the output for a++ +b

#include<stdio.h>
int main()
{
    int a=5, b=2; 
    printf("%d",a++ + b); 
}

For the above program again I'm getting output as 7 (which is again correct according to lexical analysis)

But when I wrote a program to print the outputs for both a+++b and a++ +b I'm getting different outputs

#include<stdio.h>
int main()
{
    int a=5, b=2; 
    printf("%d",a+++b); 
    printf("\n%d",a++ + b); 
}

The output is 7 for a+++b (which is correct) and 8 for a++ +b (which is wrong).

Can anyone point out the error in the third program?

Mureinik
  • 297,002
  • 52
  • 306
  • 350

2 Answers2

2

The issue here isn't the space in the second statement, it's the fact you have two of them. After the first statement (to be exact, after a++ is called), the value of a is incremented and is now 6. So a++ + b will clearly return 8. If you omit the first printf call and just call the second one, you'll get 7 as you expect.

Mureinik
  • 297,002
  • 52
  • 306
  • 350
  • The increment can occur any time after `a` is evaluated (yielding `5`) and before the sequence point that occurs before the function is called. The operator is not a function call. – Jonathan Leffler Sep 03 '22 at 13:44
2

a++ is post-fix increment. It evaluates to a and increments the variable a by 1 before the enclosing printf() is called in this case(*).

So after the first printf() the value of a is 6.

So what do you now expect from the second printf?

Operators like post-fix ++ are expressions (have a value) and instructions (have an effect). They cause endless confusion bugs and undefined behaviour to novices and bite the most seasoned programmers on the ass from time to time.

(*) These operators are useful and have their place but exactly when these operators take effect is complex sometimes counter intuitive and I recommend you don't use them in complex expressions to begin with or even ever. They're a bit of a throw back to when compilers didn't optimise code for you and the programmer had to help!

Persixty
  • 8,165
  • 2
  • 13
  • 35
  • 3
    I would say that the `++` and `--` operators are powerful and useful and, when used properly, they are neither confusing nor something to be avoided. Paradoxically, they're confusing and ill-defined mostly in the test programs that beginning programmers write when they're trying to understand them. Code like `i++ + i++` and `printf("%d %d %d\n", a++, ++a, a)` is badly undefined, yet neither of those fragments has ever been written in a real program, so their troublesomeness doesn't matter nearly so much in practice. – Steve Summit Sep 03 '22 at 13:33
  • That's why I said don't use them in complex expressions. If you write `for(int i=0;i – Persixty Sep 03 '22 at 13:37
  • I don't believe `++` and `--` were invented for efficiency. I'm pretty sure even the earliest C compilers could emit good code for "longhand" forms like `i = i + 1`. I believe `++` and `--` were invented with the goal of programmer convenience, and writing concise code. In one sense they're just contractions, like writing "don't" instead of "do not". – Steve Summit Sep 03 '22 at 13:45
  • Avoiding overly complex (or outright undefined) expressions is certainly a worthy goal. But you recommended avoiding the operators "or even ever", and that's what I'm disputing. – Steve Summit Sep 03 '22 at 13:46
  • @Steve Summit I tried running the code printf("%d %d %d\n", a++, ++a, a) with a=5 and I got the output as 6 7 7. Shouldn't it be 5 7 7? – Siddharth Sengupta Sep 03 '22 at 14:31
  • @SiddharthSengupta The arguments to a function aren't required to be evaluated in any particular order. – zwol Sep 03 '22 at 14:34
  • @SiddharthSengupta You might be joking, but if not, run, don't walk, to [this question](https://stackoverflow.com/questions/949433) and read at least [this answer](https://stackoverflow.com/questions/949433#51876456). – Steve Summit Sep 03 '22 at 14:50
  • @SiddharthSengupta Now you've gone into indeterminately sequenced. When I said 'before the enclosing printf() is called' I was being specific. The key understanding is that the evaluation of even `++a` does not mean the side-effect amounting to `a=a+1` takes place at the same time. You could get 5,6,5 as output above. But if you then print the value of a find it's 7 because the 2 increments were merged together. When I said counter-intuitive I also meant it. – Persixty Sep 03 '22 at 15:27
  • @SteveSummit I understood your answer, and I got my doubt cleared but in the last part of your answer you wrote "In the case of x = x++ + ++x, on the other hand, there's no way to fix it. There's no way to write it so that it has guaranteed behavior matching your expectations", but according to lexical analysis the tokens x=(x++)++ +(x) will be generated by the lexical analyzer for the statement "x=x++ + ++x". Because (x++) is not a lvalue object for the post-increment operator and its a rvalue object, so isn't the error expected from the above statement? – Siddharth Sengupta Sep 03 '22 at 15:30
  • @SteveSummit It's worth noting that Dennis Ritchie thinks `++x` exist (note inherited from B) because "its translation was smaller than x=x+1". Translation meaning 'to machine instructions'. That's why I think it's a bit of a throw-back because that's what the people who were they say. They didn't use the actual auto-increment cells in the PDP-7 or PDP-11 but were still shorter in instructions than an non-optimising compiler for x=x+1. This is a great read (honest): https://www.bell-labs.com/usr/dmr/www/chist.pdf – Persixty Sep 03 '22 at 15:43
  • 1
    @Persixty I've read that paper many times, thanks, but I completely forgot it said that about the translation of `++x`. Huh. – Steve Summit Sep 03 '22 at 17:41
  • 1
    @SiddharthSengupta Lexical analysis does pay attention to whitespace. If you wrote `x++++++x` it would parse as `x++ ++ +x` and would draw the lvalue error as you suggest. But if you write `x++ + ++x` it will be lexed and parsed the way it looks. See also [question 20.21b](https://c-faq.com/misc/quintplus.html) in the [C FAQ list](https://c-faq.com). – Steve Summit Sep 03 '22 at 17:45