Postfix increment operator evaluation [duplicate] - c

This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 5 years ago.
Are postfix increment/decrement operators evaluated after the expression is evaluated or after the entire statement is evaluated ?
#include<stdio.h>
void main()
{
int a=0;
int b=0;
printf("%d %d",a||b,b++); // Output is 1 0
}
My compiler evaluates the printf arguments from right to left. The answer of expression a||b is 1, it means that b has incremented before a||b has been evaluated(i.e b is incremented immediately after evaluating the expression b++)
I read here Incrementing in C++ - When to use x++ or ++x? that postfix increment/decrement are evaluated after the entire statement.
Which is correct?

The order of evaluations of function arguments is unspecified. All side effects related to the argument evaluations are applied before the control will be passed to the called function.
From the C Standard (6.5.2.2 Function calls)
10 There is a sequence point after the evaluations of the function
designator and the actual arguments but before the actual call.
Here is a demonstrative program
#include <stdio.h>
struct
{
int x;
} a = { 0 };
void f( int x )
{
printf( "x = %d\n", x );
printf( "a.x = %d\n", a.x );
}
int main(void)
{
f( a.x++ );
}
Its output is
x = 0
a.x = 1
Due to the side effect in this call then one argument is dependent on a side effect of other argument and the evaluation of the side effect indeterminately sequenced relative the arguments
printf("%d %d",a||b,b++);
the program has undefined behavior.
There are four operators in C when side effects are sequenced between operand evaluations. They are the logical AND operator (&&), logical OR operator (||)comma operator (,), and the conditional operator ( ?:).
For example
#include <stdio.h>
int main(void)
{
int x = 0;
printf( "x = %d\n", x++ == 0 ? x : x - 1 );
}
The program output is
x = 1
The side effect of the evaluation of the expression x++ was sequenced before the evaluation the expression x after the ? sign.

The top answer of the question you linked to is inaccurate. The increment in x++ is only guaranteed to happen after determining the value of the expression, and sometimes before evaluating a containing expression, but there are no other guarantees on when it happens.
In particular, since side effects of arguments to the same function call are indeterminately sequenced, that program has undefined behavior.

Related

Is formatted output equivalent? [duplicate]

This question already has answers here:
What is the difference between prefix and postfix operators?
(13 answers)
Closed 11 months ago.
When I was doing the practice questions today, I found that the outputs of printf("%d\n",x--); and printf("%d\n",x); are the same.
I changed it to printf("%d\n",x++); and found to be the same. I want to know why.
#include<stdio.h>
int main()
{
int x;
scanf_s(" %d", &x);
if (x++ > 5)
printf("%d",x);
else
printf("%d\n",x--);
return 0;
}
You used the post-decrement/-increment operators.
x-- decrements x and returns the original value of x.
x++ increments x and returns the original value of x.
To get the desired behaviour, use the pre-decrement/-increment operators.
--x decrements x and returns the modified x.
++x increments x and returns the modified x.
That's simple and you can understand as well if you know the usage of these 2 kind of operators.
Post Increment/Decrement Operator e.g. a++, a-- etc.
So when we use it in the statement, the current value of the variable will be used and post that its value is incremented by 1.
Just take a look into my comments at end of statements (shows the o/p).
#include<stdio.h>
int main()
{
int x;
scanf_s(" %d", &x); // 10
printf("%d", x++); // 10
printf("%d", x); // 11
return 0;
}
Pre Increment/Decrement Operator, e.g. ++a, --a etc.
So when we use it in the statement, first its value of variable is incremented by 1 & then the incremented value will be used.
#include<stdio.h>
int main()
{
int x;
scanf_s(" %d", &x); // 10
printf("%d", ++x); // 11
printf("%d", x); // 11
return 0;
}
I think, now it's clear to you. For info on usages, just take a look into Usage of Pre/Post Increment & Decrement operators in C.
According to the C Standard (6.5.2.4 Postfix increment and decrement operators)
2 The result of the postfix ++ operator is the value of the
operand. As a side effect, the value of the operand object is
incremented (that is, the value 1 of the appropriate type is added to
it)
and
3 The postfix -- operator is analogous to the postfix ++ operator,
except that the value of the operand is decremented (that is, the
value 1 of the appropriate type is subtracted from it).
Consider this pair of calls of printf
int x = 10;
printf( "%d\n", x++ );
printf( "%d\n", x );
The output is
10
11
That is the value of the expression of x++ is the value of its operand that is equal to 10. As a side effect the variable x is increased and in the second call of printf the new value of x after applying the side effect is outputted.
You can imagine this call
printf( "%d\n", x++ );
like
printf( "%d\n", x ), x += 1;
Opposite to postfix increment and decrement operators the values of unary increment (++x) and decrement (--x) operators are values after incrementing and decrementing their operands.
From the C Standard (6.5.3.1 Prefix increment and decrement operators)
2 The value of the operand of the prefix ++ operator is incremented.
The result is the new value of the operand after incrementation.
and
3 The prefix -- operator is analogous to the prefix ++ operator,
except that the value of the operand is decremented.

Return and ++ in C

The output of:
#include <stdio.h>
int Fun1(int *X)
{
return (*X)++;
}
int main(void)
{
int a = 0, b = 5;
a = Fun1(&b);
printf("a = %d. b = %d.\n", a, b);
}
is:
a = 5. b = 6.
When we return (*X)++, should not the function execution stop when we return (*X), so the ++ is not executed?
The return statement causes its operand to be evaluated. Evaluation of an expression includes both computation of its value and of its side effects.
The C standard specifies the behavior of postfix ++ in 6.5.2.4 2:
The result of the postfix ++ operator is the value of the operand. As a side effect, the value of the operand object is incremented (that is, the value 1 of the appropriate type is added to it)…
Similarly, if we wrote a = b++;, the assignment would not just assign the value and be done. The side effect occurs too.
The side effects are part of what an expression does, per 6.5 1:
An expression is a sequence of operators and operands that specifies computation of a value, or that designates an object or a function, or that generates side effects, or that performs a combination thereof…
This:
*X = (*X)++ + ++(*X)
is undefined behavior, so you cannot really predict the result: Why are these constructs using pre and post-increment undefined behavior?
Also, if you want to know what undefined behavior is: Undefined, unspecified and implementation-defined behavior
This:
return (*X)++;
is equivalent to this: (Provided that X is an int)
int tmp = (*X)++;
return tmp;
return does not do anything magical here. I refer to #Eric's answer for a more in depth explanation of postfix operator.
When we return (*X)++, should not the function execution stop when we return (*X), so the ++ is not executed?
No

Increment and decrement operators in one statement in C [duplicate]

This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Undefined, unspecified and implementation-defined behavior
(9 answers)
Closed 3 years ago.
I know it is theoretically undefined behavior and of course bad style. This is the example of a school (I am not the pupil).
But why do I get 7 (example a) resp. 1 (example b) out of this operation:
Online example:
https://onlinegdb.com/B172lj8k8
a:
#include <stdio.h>
int main()
{
int i = 2;
printf("%d; i=%d", ++i + i++, i);
return 0;
}
b:
#include <stdio.h>
int main()
{
int i = 2;
printf("%d; i=%d", ++i - i++, i);
return 0;
}
In my opinion the output should be 6 and 2.
Execute i++, yield 2, increment i
Execute ++i yield 4
Additon 2 + 4
The other example should be 4 - 2.
Exexcuting the increment in a statement seems to yield the result of the increment immediately, no matter if it is postfix or prefix, which is odd. Or do I get it wrong totally?
The order in which the arguments passed to a function are evaluated is not specified, and the order of evaluating the operants of + is unspecified, too.
So in printf("%d %d", i+1, i-1), for example, you cannot rely on the order of evaluation of the arguments; i+1 might be evaluated after i-1, actually; You will not recognise, since the evaluation of the one does not effect the result of the other.
In conjunction with "side effects" like the post-increment i++, however, the effect of incrementing i at a specific point in time might influence the result of other evaluations based on i. Therefore, it is "undefined behaviour" in C, if a variable is used more than once in an expression and a side effect changes its value (formally, to be precise, if there is no sequence point in between).

foo(x++, y) :: Does the x always incremented after to be send as argument?

Is the increment in case of an expression involving x++ always made after the variable to be copy to a function ?
The call :
foo(x++, y);
The function :
int foo(int x, int y)
{
return x*y;
}
Is that a undefined behavior for all compilers?
Let's see the official descriptions here to get a deeper understanding.
For the postfix operator, quoting C11, chapter §6.5.2.3
The result of the postfix ++ operator is the value of the operand. As a side effect, the
value of the operand object is incremented (that is, the value 1 of the appropriate type is
added to it). [...] The value computation of the result is sequenced before the side effect of
updating the stored value of the operand.
and, regarding the function call, chapter §6.5.2.3
There is a sequence point after the evaluations of the function designator and the actual
arguments but before the actual call. Every evaluation in the calling function (including
other function calls) that is not otherwise specifically sequenced before or after the
execution of the body of the called function is indeterminately sequenced with respect to
the execution of the called function.
So, as per above description, there's nothing problematic in your code as shown above.
The old value of x is passed and then, the value is increased.
However, please note the last part of the second quote, you need to maintain the sanity of the code. For example, you need to make sure, there's no change in value without having a sequence point in between. Something like
foo(x++, x++, y);
will be a problem as, you're trying to changing the same variable (x) more than once.
Consider the following program
#include <stdio.h>
int x;
void foo(int x1 )
{
extern int x;
printf( "x1 = %d\n", x1 );
printf( "x = %d\n", x );
}
int main(void)
{
foo( x++ );
return 0;
}
Its output is
x1 = 0
x = 1
Thus as it is seen the value of the expression x++ is the value of the operand before incrementing
x1 = 0
However the side effect was applied before the function gets the control
x = 1
The program is well-formed and there is no undefined behavior.
Whenever post increment is used, the original value of the variable will be sent to the function. And after that, the value of x will be incremented.

Evaluation of Expressions inside printf in C [duplicate]

This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 6 years ago.
I know that multiple expressions are evaluated from right to left.
Ex:
int i = 0;
printf("%d %d %d", i, i++, i++); // Prints 2 1 0
But when it comes to each expression to be evaluated, i'm not getting if it is from right to left or vice versa.
int main()
{
int a = 1, b = 1, d = 1;
printf("%d", a + ++a); // Result = 4
}
Considering evaluation from left to right, the preceding code should be evaluated as 1 + 2 = 3
int main()
{
int a = 1, b = 1, d = 1;
printf("%d", ++a + a); // Result = 4
}
And this should Evaluate as 2 + 2 = 4
But in both the cases the answer is 4.
Can anyone explain how these expressions are evaluated?
I know that multiple expressions are evaluated from right to left.
No. The order of evaluation of function parameters is unspecified behavior. Meaning you can't know the order, it may differ from system to system or even from function call to function call. You should never write programs that rely on this order of evaluation.
In addition, there is no sequence point between the evaluation of function parameters, so code like printf("%d", ++a + a); also invokes undefined behavior, see Why are these constructs (using ++) undefined behavior?.
Please note that operator precedence and operator associativity only guarantees the order in which an expression is parsed! This is not related to the order of evaluation of the operands. (With a few special exceptions such as || && , ?: operators.)

Resources