This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 9 years ago.
int a[]={10,20,30,40};
int x=0;
int v=a[++x]+ ++x + a[--x];
printf("%d",v);
What will be the output of this program??
Completely confused with the output. No way it is going to be done according to my operator precedence knowledge.
According to me, in this expression Array subscripting [] has highest precendence and should be executed first. so both [] should be executed first from left to right. In this case value of x will increment first, then decrement and finally come back to 0. so expression will become int v=a[0] + ++x + a[0]. Then the pre increment is having highest precedence and it will be incremented to 1. so our expression will become int v=a[0]+1+a[0]. so final output will be 21.
But this is not the case. I have checked on different compiler implementations and no one prints 21.
I am much surprised because the value printed is 43, which is no where understandable to me. That's why I want someone to help me understand and come to the result 43.
The link which others have suggested is using only increment and same rvalue and lvalue cases. But this is somewhat different and not clear. I tried to contruct expression tree for this and solve but 43 is no where in scope.
Output of this code:
int v=a[++x]+ ++x + a[--x];
is undefined and it depends on the compiler implementation.
Related
This question already has answers here:
Why does increment operation ++a++ not work, at least in C?
(3 answers)
Closed 6 months ago.
Why is the output of the following program showing compile time error?
Please explain "lvalue required"
#include<stdio.h>
int main()
{
int a=5;
printf("%d", ++a++);
return 0;
}
A language-lawyer proof explanation is a bit lengthy, here's an attempt at a simplified explanation:
The "l" in "lvalue" comes from "left" as in a value that can appear on the left hand side of an assignment operation, which includes many named variables:
int a;
a = 42; // a is an lvalue and can be assigned to
Now due to operator precedence the expression ++a++ is parsed as ++(a++). And since a++ modifies a "later" but, as expression, evaluates to the current value of a it "returns" a copy of this current value of a, a temporary value.
This temporary value is unnamed (it is not a) and it's not an lvalue, wherefore it can't be assigned to.
You can't write a++ = 42 because you'd be assigning to the temporary value, rather than a variable, and for the same reason you can't write ++a++.
Again, you'll have to dive much deeper, and also give yourself some time to develop an intuitive feeling for what an lvalue is, then this will become much clearer.
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.
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.
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.
This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 5 years ago.
I came across a very interesting fact while executing the following a simple c program:
#include<stdio.h>
int main( )
{
int k=0;
printf("%d%d%d", k++, k, ++k);
return 0;
}
in windows it was showing output as: 1 1 1
but in linux(ubuntu) it was showing as: 1 2 2
why is it so?
It's undefined behaviour. When there are no / ambiguous sequence points. See this wikipedia article:
http://en.wikipedia.org/wiki/Sequence_point
There are two problems. First is that the order in which the expressions k++, k, and ++k in the printf call are evaluated is not specified; the compiler is free to evaluate them in any order it sees fit. Second is that an object may not have its stored value updated more than once between sequence points by the evaluation of an expression. Both k++ and ++k attempt to update the value stored at k, and there is no sequence point between those expressions, so the behavior is undefined; any result is permitted.
The standard does not specify an ordering in which the arguments of a routine are evaluated.
Writing code that depends on the ordering is not portable.