Post-Decrement operator [duplicate] - c

This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 7 years ago.
some body please tell me what will be the value of x after(in c language)
x=1;
x=x--&&++x;
I think it should be 0 because x&&++x will give 1 and post decrement will make it 0.
But when I entered this on computer result was 1.
Why post decrement is not working here.
I am thinking like this:
precedence of pre increment is above && so both x should be treated as 2 (Boolean value true ) so x&&++x will give 1 and the post-decrement should decrement it to 0.
This is not a duplicate question as this is not the case of undefined behavior its about how post-decrement works.

x=x--&&++x;
This causes undefined behaviour as value of x is changed more than once between two sequence points.
Expression x-- && ++x is well defined as it has internal sequence point due to && , but when you assign it to x , it causes undefined behaviour.
Therefore ,expression exhibits undefined behaviour.
C99 §6.5: “2. Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be read only to determine the value to be stored.”

While the result of (x--)&&(++x); is well defined, due to short circuit evaluation.
the result of your assignment
x = (x--)&&(++x); is not.
A simpler example would be:
x = x--;
which, as Paul and Art note in the comments:
modifies the value of x twice within the same expression without a
sequence point between the modifications.
EDIT: fixed my initial errornous answer, which stated that the result of the assignment is defined.

Inspite of the fact that there are exams in my university I wasn't able to stop thinking about this question and I think I have finally found the solution.
Firstly, post decrement operator will be executed as it is in the left of &&, it will decrement the value of x to 0 but x-- will be 1(previous value of x ) as left side is 1 right side will be executed here ++x will assign value 1 to x and value of ++x will also be 1 so && operator will return value 1.Now, although there is no sequence point between pre-increment operator and assignment operator both are assigning value 1 to x so this is totally defined that value of x will be 1 after the whole code is executed.

Related

C: What is the output of the following code? And please explain [duplicate]

This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 7 years ago.
int a = 5;
if(a==a++){
printf("true 1");
}
if(a==++a){
printf("true 2");
}
When I run this code, it prints "true 2". I do not understand how. Please help.
Also, how is logical equivalence computed in precedence with increment operators?
The order of evaluation in a==++a is not defined by the standard. Thus the ++ can be performed before the comparison or after comparison. With another compiler you can get different results. This is called 'UB', or 'Undefined Behavior'.
This code will give Undefined Behavior in many ways. But if you initialize a, the difference is that ++a will return the incremented value, while a++ will return the new value.
Also, in for loops, you should use ++a and you will not go wrong.
Let's evaluate your problem.
In the first case, when you compare a with the incremented value of a (as a++ return the incremented value), so it is false. Example: a has 5, and the incremented value is 6. So, as they do not match, it will be a false.
In the second case, when you compare a with the old value of a (as ++a returns the original value), you get true. Example: a has 5 and when you increment it using ++a, you get the old/original value, which is also 5. Thus, you get a true.

Using unary increment/decrement in printf function [duplicate]

This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 7 years ago.
I declared a variable suppose i = 1
And then I used unary decrement operator in printf function
printf("%d %d",i--,i);
I expected the output to be 1 0 but the output displayed was 1 1
Why the value of i is not getting decremented?
The order of evaluation of function parameters is not guaranteed in C. It might be left to right, or it might be right to left. It's up to the compiler implementation.
It is undefined behaviour to have multiple references to a variable in combination with increment or decrement operators in one expression.
i-- decrements the value after being evaluated.
post-increment and post-decrement creates a copy of the object, increments or decrements the value of the object and returns the copy from before the increment or decrement. http://en.cppreference.com/w/cpp/language/operator_incdec
Furthermore, the order of evalation is not guaranteed. So i (the second argument) could be evaluated before i-- (the first one)

Why the expression a==--a true in if statement? [duplicate]

This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 9 years ago.
#include <stdio.h>
int main()
{
int a = 10;
if (a == a--)
printf("TRUE 1\t");
a = 10;
if (a == --a)
printf("TRUE 2\t");
}
Why is the second if statement true?
Output is:
TRUE 1 TRUE 2
Is this happening due to Undefined behavior because I am comparing same variable with its decremented value?
Correct, the condition evaluates to true because you see undefined behavior: if a variable with an operator that has side effects is used in an expression, it is illegal to use the same variable again in an expression that has no sequence points (== does not have sequence points).
This is because the compiler is free to apply the side effect of -- at any time that it wishes, as long as the value that is used when evaluating the expression is correct (i.e. the value before the decrement for postfix notation, or the value after the decrement for the prefix notation).
a-- decrements a after the expression has evaluated, effectively meaning when a == a is calculated, it's 10 == 10, which is true.
--a decrements a before the expression has evaluated, effectively meaning when a == a is actually calculated, a has already been decremented, so it's 9 == 9, which is again true.
Pre and post decrements can't happen in the middle of expressions. They happen before or after them.
This is because associativity of == operator is left to right.
a==a--
In this expression, first both sides will be compared (10==10), and then a is decreased to 9
a==--a
in this expression first the value of a is decreased to 9 then compared to a (which has become 9)
So, both are true.

Confused with pre and post increment operator [duplicate]

This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 9 years ago.
hello I am learning basics of C programming language, recently i have studied about post and pre increment/decrement operators and also about lvalue and rvalue, the following program shows an error, lvalue required, according to me it should give a value of 6, Can anyone please explain why?
int main(){
int x = 8, y;
y = --x--;
printf("y=%d",y);
return 0;
}
Please explain, why is it so?
Well, let's see what is happening in --x--.
At first, post-decrement executes: --(x--).
(x--) = 7.
After that result of this operation is placed to the original structure:
--7 - doesn't make sense - thus you get lvalue required error
The statement y = --x--; will give you the following error on compilation in C. lvalue required. This is because the post decrement operator -- will return an rvalue after operating on the variable x. So there are no lvalue to perform the pre decrement operator -- afterwards.
But this is one point where C and C++ differs. In C the following statement will also give you the same error lvalue required.
y = (--x)--;
But in C++ the statement y = (--x)--; will compile fine and the value of y is 7. Because unlike C, C++ returns an lvalue after performing the pre decrement operator on variable x.
L Value is left operand of assignment operator which should refer to memory location.As explained by #Pavel your Lvalue is becoming a value not object so you are getting error.
--x means x = x-1 but in your case it is becoming --7 which will be equivalent to 7 =7-1 which is definitely not valid expression.
Other than this more than one operation on same variable without any sequence point in between, results undefined behaviour.
C order of operations specifies that postfix operators have precedence over the prefix operators. The -- postfix operator returns the current value (an rvalue) of the operand and then decrements the operand. Then the prefix decrement operator would be applied...but the decrement/increment operators need lvalue operands since they by definition modify their operands. So, as the compiler says, an lvalue is required.
You should not use it at a time because you will not understand the behavior of compiler. So, you need to guide your code so that they will forced to do what you like.
Now come to your point. If you want to decrease the value by one you can use a-- or --a. They will do the same. If a = 5 and you use b=a-- you will get b = 5 and a = 4 where if you use b=--a you will get b = 4 and a = 4 in --a the value is assigned immediately and in a-- value will be assigned after statement is complete. Hope you are clear.
L value required error shown when it doesn't find any suitable variable where it can be assigned.

Why is `x-- > 0` not undefined behaviour, while `x = x--` is?

As everyone knows, this loops through zero:
while (x-- > 0) { /* also known as x --> 0 */
printf("x = %d\n", x);
}
But x = x-- yields undefined behaviour.
Both examples need some 'return' value of x--, which is not there I guess. How can it be that x-- > 0 is defined but x = x-- is not?
Because in x = x-- you're modifying the value of x twice without an intervening sequence point. So the order of operations is not defined. In x-- > 0 the value of x is modified once, and it is clearly defined that result of evaluating x-- will be the value of x before the decrement.
I don't know where you got that idea about "need some 'return' value of x--, which is not there". Firstly, it is not exactly clear what you mean. Secondly, regardless of what you mean this doesn't seem to have anything to do with the source of undefined behavior in x = x--.
x = x-- produces undefined behavior because it attempts to modify x twice without an intervening sequence point. No "need" for any "return value" is involved here.
The underlying problem with x = x-- is that it has two side-effects that occur at undefined moments in undefined order. One side-effect is introduced by the assignment operator. Another side-effect is introduced by postfix -- operator. Both side-effects attempt to modify the same variable x and generally contradict each other. This is why the behavior in such cases is declared undefined de jure.
For example, if the original value of x was 5, then your expression requires x to become both 4 (side-effect of decrement) and 5 (side-effect of assignment) at the same time. Needless to say, it is impossible for x to become 4 and 5 at the same time.
Although such a straightforward contradiction (like 4 vs 5) is not required for UB to occur. Every time you have two side-effects hitting the same variable without intervening sequence point, the behavior is undefined, even if the values these side-effects are trying to put into the variable match.
In order to understand this you need to have a basic understanding of sequence points. See this link: http://en.wikipedia.org/wiki/Sequence_point
For the = operator there is no sequence point, so there is no guarantee that the value of x will be modified before it is again assigned to x.
When you are checking the condition in the while loop x-- > 0, x-- is evaluated and the value is used in the relational operator evaluation so there is no chance of undefined behaviour because x is getting modified only once.
Just to add something to other answers, try reading this wikipedia page about sequence points.
I suggest reading https://stackoverflow.com/a/21671069/258418. If you chuck together that = is not a sequence point, and the compiler is free to interleave operations, as long as they are not separated by a sequence point from the answers linked by you, you see that i.e. the following two sequences would be legal:
load i to reg
increment i
assign reg to i
=> i has previous value of i
load i to reg
assign reg to i
increment i
=> i has value of previous value of i + 1
In general: avoid assigning (this includes modiying by pre/post ++/--) to the same variable twice in one expression.

Resources