[SOLVED]Postfix and Prefix operator

Thread Starter

Kittu20

Joined Oct 12, 2022
463
I have tried a lot but I don't understand fully how postfix and prefix operator work in c language

How compiler execute line 8 and line 10

I have written code

C:
#include<stdio.h>

int main()
{
   int X = 1;                // Compiler allocates memory for X and assign value 1
   int Y;                    // Compiler only allocate memory for variable Y
 
   Y =  X++;                 // x become 2 , Y become 1
 
// Y = ++X;                   x become 2 , Y become 2  
 
   printf("X = %d \n", X);
   printf("Y = %d", Y);
 
    return 0;
}
X = 2
Y = 1
 

WBahn

Joined Mar 31, 2012
29,978
Think of the increment operators as just expressions that yield a value (which is exactly what they are).

x++

is an expression that evaluates to the current value of x, while

++x

is an expression the evalutes to one greater than the current value of x.

In addition to the value, each expression also happens to have a side effect, namely that it changes the value stored in x.

One common mistake that programmers make is that they assume they know WHEN that side effect will take place, but they don't. So if you have either of those operators in an expression, be sure that you only use that variable being operated on once.

For example:

x = 10;
y = 3*x - x++;

You might think that y will be 20, but it might be 23. The compiler is free to apply the side effect at any time from the beginning of the expression evaluation to the end and it is free to evaluate expression elements in any order (except where the standard is explicit). Different compilers make different choices.

If you want more information, look up "sequence points in C".
 

ApacheKid

Joined Jan 12, 2015
1,533
Think of the increment operators as just expressions that yield a value (which is exactly what they are).

x++

is an expression that evaluates to the current value of x, while

++x

is an expression the evalutes to one greater than the current value of x.

In addition to the value, each expression also happens to have a side effect, namely that it changes the value stored in x.

One common mistake that programmers make is that they assume they know WHEN that side effect will take place, but they don't. So if you have either of those operators in an expression, be sure that you only use that variable being operated on once.

For example:

x = 10;
y = 3*x - x++;

You might think that y will be 20, but it might be 23. The compiler is free to apply the side effect at any time from the beginning of the expression evaluation to the end and it is free to evaluate expression elements in any order (except where the standard is explicit). Different compilers make different choices.

If you want more information, look up "sequence points in C".
This is a good argument for strictly avoiding these contrivances, expressions that are also assignments are a terrible idea.
 

WBahn

Joined Mar 31, 2012
29,978
This is a good argument for strictly avoiding these contrivances, expressions that are also assignments are a terrible idea.
They serve a purpose, particularly in resource-starved or performance-critical situations.

They can also add to the readability of code, especially when used as just an assignment statement.
 

Thread Starter

Kittu20

Joined Oct 12, 2022
463
I was under the impression that program would give output 5 5 6 6 6 but I don't understand why it gives output 8 7 8 5 8
C:
#include<stdio.h>

int main()
{
    int i = 5;
    
    printf("%d %d %d %d %d", i, i++,++i, i++, i);
    return 0;
}
 

WBahn

Joined Mar 31, 2012
29,978
I was under the impression that program would give output 5 5 6 6 6 but I don't understand why it gives output 8 7 8 5 8
C:
#include<stdio.h>

int main()
{
    int i = 5;
   
    printf("%d %d %d %d %d", i, i++,++i, i++, i);
    return 0;
}
The order in which the arguments to a function are evaluated are unspecified. Furthermore, exactly when side effects are applied is unspecified other than that they must occur before the next sequence point.
 

xox

Joined Sep 8, 2017
838
Another "gotcha" can be the use of macros with expressions having side-effects.

Code:
#include <stdio.h>

#define NEGATIVE(expression) ((expression) > 0 ? -(expression) : (expression))

int main(void) {
  int value = 1024;
  printf("value:              %d\n", value);
  printf("NEGATIVE(value++): %d\n", NEGATIVE(value++));
  printf("value:              %d\n", value);
}
Output:

value: 1024
NEGATIVE(value++): -1025
value: 1026
Defining NEGATIVE() as a function instead, we of course get:

value: 1024
NEGATIVE(value++): -1024
value: 1025
For that very reason, macros which can result in side-effects especially should be named with ALL CAPS.
 

ApacheKid

Joined Jan 12, 2015
1,533
I was under the impression that program would give output 5 5 6 6 6 but I don't understand why it gives output 8 7 8 5 8
C:
#include<stdio.h>

int main()
{
    int i = 5;
 
    printf("%d %d %d %d %d", i, i++,++i, i++, i);
    return 0;
}
This is a great example of why C is a huge risk, a source of bewildering, frustrating problems. Unspecified argument evaluation order is only part of the problem too, being able to embed an assignment within an expression is another.

The worst kind of language for systems that are expected to control complex devices with precision and predictability (are you listening Tesla?).

My position is to avoid these combined operator/assign features, keep assignments separate from expressions as much as you can, you think C is confusing, wait until you use C++ !
 

xox

Joined Sep 8, 2017
838
This is a great example of why C is a huge risk, a source of bewildering, frustrating problems. Unspecified argument evaluation order is only part of the problem too, being able to embed an assignment within an expression is another.


The worst kind of language for systems that are expected to control complex devices with precision and predictability (are you listening Tesla?).


My position is to avoid these combined operator/assign features, keep assignments separate from expressions as much as you can, you think C is confusing, wait until you use C++ !
IMO there is nothing inherently wrong with C, it just takes a bit more discipline to write safe and robust programs. I for one have worked on some very large but well constructed C codebases without any major issues. That said, many people do struggle with it, and buggy C programs are obviously rather common. There is definitely a learning curve involved; It generally does take a few years to actually master the language.
 

ApacheKid

Joined Jan 12, 2015
1,533
IMO there is nothing inherently wrong with C, it just takes a bit more discipline to write safe and robust programs. I for one have worked on some very large but well constructed C codebases without any major issues. That said, many people do struggle with it, and buggy C programs are obviously rather common. There is definitely a learning curve involved; It generally does take a few years to actually master the language.
This is true in a literal sense, but a language where the same, relatively simple code, can produce different outputs on different platforms or with different vendors' compilers, is a poor choice for intricate hardware control application IMHO anyway.

Java and C# impose a left-to-right argument evaluation order, right away that simple policy eliminates a whole class of bugs (they still allow ++ and -- though).

Of course evaluation order doesn't matter at all if evaluating the arguments has no side effects, but that's a different problem area all together.
 

MrChips

Joined Oct 2, 2009
30,712
I was under the impression that program would give output 5 5 6 6 6 but I don't understand why it gives output 8 7 8 5 8
C:
#include<stdio.h>

int main()
{
    int i = 5;
   
    printf("%d %d %d %d %d", i, i++,++i, i++, i);
    return 0;
}
You wrote that only as a test. If you cannot predict the outcome then you should not write code like that.
Write code that you can predict the order of execution.
C:
#include<stdio.h>

int main()
{
    int i = 5;
    printf("%d",  i);
    printf("%d",  i++);
    printf("%d",  ++i);
    printf("%d",  i);
    return 0;
}
 

xox

Joined Sep 8, 2017
838
This is true in a literal sense, but a language where the same, relatively simple code, can produce different outputs on different platforms or with different vendors' compilers, is a poor choice for intricate hardware control application IMHO anyway.

Java and C# impose a left-to-right argument evaluation order, right away that simple policy eliminates a whole class of bugs (they still allow ++ and -- though).

Of course evaluation order doesn't matter at all if evaluating the arguments has no side effects, but that's a different problem area all together.
No language is perfect. At the end of the day, it is just a tool to get the job done. Blaming the tool rather than simply learning how to use it effectively IMO seems like looking for something to complain about.

Not many languages can do all of the things that C can either. Java and C# are not only require huge, monolithic runtimes, but their features are also severely lacking in many ways. (And I say that as a professional C#/Java programmer.)
 

MrChips

Joined Oct 2, 2009
30,712
Anyone can write cryptic code.
It takes some effort to write code that is clear and easy to follow, regardless of the programming language.

Some programming languages such as APL and SNOBOL appear to encourage writing code that is difficult to follow.
 

ApacheKid

Joined Jan 12, 2015
1,533
Anyone can write cryptic code.
It takes some effort to write code that is clear and easy to follow, regardless of the programming language.

Some programming languages such as APL and SNOBOL appear to encourage writing code that is difficult to follow.
APL is only hard to follow if you don't know APL, APL developers have no trouble following it, understanding what it's doing.
 

ApacheKid

Joined Jan 12, 2015
1,533
No language is perfect. At the end of the day, it is just a tool to get the job done. Blaming the tool rather than simply learning how to use it effectively IMO seems like looking for something to complain about.

Not many languages can do all of the things that C can either. Java and C# are not only require huge, monolithic runtimes, but their features are also severely lacking in many ways. (And I say that as a professional C#/Java programmer.)
Well assembler can do anything C can, is that an argument for using assembler for everything? Clearly not. There's also nothing inappropriate about blaming a broken tool for the shortcoming it might lead to in a finished product.
 

nsaspook

Joined Aug 27, 2009
13,086
Well assembler can do anything C can, is that an argument for using assembler for everything? Clearly not. There's also nothing inappropriate about blaming a broken tool for the shortcoming it might lead to in a finished product.
Broken? That's a ridiculous baiting statement about C. The rest of the world seems be able to use it daily for useful work without waiting indefinitely for some finished product.
 
Last edited:

xox

Joined Sep 8, 2017
838
Well assembler can do anything C can, is that an argument for using assembler for everything? Clearly not. There's also nothing inappropriate about blaming a broken tool for the shortcoming it might lead to in a finished product.
And it does so in a very platform-specific way. Whereas C compiles to basically ANY kind of machine code.

Having said that, yes, assembler is a tool too. And if you want or have to implement something using that particular tool, that is fine. (Regarding that, I prefer the INTEL syntax over AT&T.)

I also do not agree that C is broken. In fact I am so confident of that, if something goes wrong in my code, I automatically know that it is my own fault. On the other hand, there are a lot of languages are truly "broken". (Did you know that no Java implementation can handle a function body consisting of more than 2^16 bytes? It's kludgy "generics" objects don't actually work very well either.)
 
Top