int val = 5;
printf("%d",++val++); //gives compilation error : '++' needs l-value
int *p = &val;
printf("%d",++*p++); //no error
Could someone explain these 2 cases? Thanks.
++val++ is the same as ++(val++). Since the result of val++ is not an lvalue, this is illegal. And as Stephen Canon pointed out, if the result of val++ were an lvalue, ++(val++) would be undefined behavior as there is no sequence point between the ++s.
++*p++ is the same as ++(*(p++)). Since the result of *(p++) is an lvalue, this is legal.
The expression ++val++ is the same as (++val)++ (or perhaps ++(val++), anyway it's not very relevant). The result of the ++ operator is not the variable, but the value, and you can't apply the operator to a value.
The expression ++*p++ is the same as ++(*(p++)). The result of p++ is the value, but the result of *(p++) is a memory location, which the ++ operator can be applied to.
also note that you're changing the address of the pointer by
int k = ++*p++;
int j = ++val++; //gives compilation error
That because you cannot pre-increment an rvalue. ++val++ is interpreted as ++(val++) because post-increment operator has higher precedence than pre-increment operator. val++ returns an rvalue and pre-increment operator requires its operand to be an lvalue. :)
int k = ++*p++; //no error
++*p++ is interpreted as ++(*(p++)), which is perfectly valid.
Related
#include <stdio.h>
int main()
{
int arr[] = {1, 2, 3, 4, 5};
int *p = arr;
++*p;
p += 2;
printf("%d", *p);
return 0;
}
Why is this code not giving any compile time error,My doubt is ++*p is evaluated as ++(*p) and *p will be constant value 1 ,when we do ++(1) which is not a l-value,why is compiler not giving an error?
*p will be constant value [...]
No, it is the same as arr[0].
So
++(*p);
is the same as
++(p[0]);
is the same as
++(arr[0]);
which is a perfectly valid statement.
Object pointer dereferencing does not itself produce the value to which the pointer points. Instead it produces an lvalue that refers to that value. In the words of the standard:
The unary * operator denotes indirection. If the operand points to a
function, the result is a function designator; if it points to an
object, the result is an lvalue designating the object. If the operand
has type "pointer to type", the result has type "type".
(C2011, 6.5.3.2/4; emphasis added)
Unary * is thus among a class of operators that can be considered to operate on the identity of an object, as opposed to on its value. The & operator and and some uses of the sizeof operator can also be considered to be in this category.
*p will be constant value
No, it won't. *p is a[0] when you do int *p = arr;. a[0] is not a constant value, and since they are the same, *p is not a constant value either.
As a result, this:
++(*p);
is equivalent to:
++(a[0]);
which increments the element at the first position of the array, as you can see clearly.
But looking back at ++(*p), one can see that:
*p dereferences the pointer, resulting in an l-value.
Then we have (*p), the l-value in parentheses.
++(*p) applies the pre-increment operator to an l-value, which is value, thus no compiler error should be generated.
Why ++(*p) is not giving l-value required error?
Dereference operator on a pointer yields a lvalue.
Therefore, *p is a lvalue and using pre-increment operator on it is valid.
Just note both the statements used by you :
++*p; // increments the value pointed by *p at that time `a[0]` by 1
p += 2; // increments the address p is storing by 2
And the reason there is no l-value required error is because in your statement :
++*p; // *p is not a constant, it is same as a[0]
When I try to compile this code
int main() {
int i = 0;
++(++i);
}
I get this error message.
test.c:3:5: error: lvalue required as increment operand
++(++i);
^
What is the error message saying? Is this something that gets picked up by the parser, or is it only discovered during semantic analysis?
++i will give an rvalue1 after the evaluation and you can't apply ++ on an rvalue.
§6.5.3.1 (p1):
The operand of the prefix increment or decrement operator shall have atomic, qualified, or unqualified real or pointer type, and shall be a modifiable lvalue.
1. What is sometimes called "rvalue" is in this International Standard described as the "value of an expression". - §6.3.2.1 footnote 64).
A lvalue is a value you can write to / assign to.
You can apply ++ to i (i is modified) but you cannot apply ++ to the result of the previous ++ operator. I wouldn't have any effect anyway.
Aside: C++ allows that (probably because ++ operator returns a non-const reference on the modified value)
The issue that the (++i) returns new integer value, and please note ++ operation needs some variable for assignment, not a value (you are trying to increment an integer not a variable), so you can use this instead :
i += 2;
or
i = i + 2;
The code is simple,I just want to test the priority between & and ++.
int main()
{
int a=10;
int *p;
int *q;
p=&++a;//error: lvalue required as unary ‘&’ operand
q=&a++;//error: lvalue required as unary ‘&’ operand
return 0;
}
when gcc compile it, two errors came out. In my opinion,a++ is a right value,but the ++a is a lvalue,so it should not be an error when use & to get it address,
It seems that you have misunderstood the difference between lvalue and rvalue. In your case both the expressions a++ and ++a are rvalues and cannot be assigned.
Here is a good description of the distinction, but the quick way to tell whether it is an lvalue is to see whether you get an error if you put it on the left side of an =.
Observe that both of the following two statements produce the same error you describe.
++a = 5;
a++ = 6;
Update: As #mafso mentioned below, ++a is indeed an lvalue in the language c++, and you will not see the error for that expression when compiling with g++.
the object of operator & is lvalue , an the same is operator ++.but after ++a is done , it returns rvalue , that's the reason wrong.
what is the order of precedence for pre ++, post ++ and * ? how these expression are parsed in VS 08 compiler.
void main(){
int arr[] ={34,11,43};
int *ptr = arr;
printf("%d",++*ptr++);
printf("%d",++ptr++);
}
explain the l value expression. i want to understand why ++*ptr++ is a valid expression, while ++ptr++ is giving error.
error: '++' needs l-value
The precedence is ++(*(ptr++)) and ++(ptr++) respectively.
ptr++ is an rvalue, because the language definition says so. (rvalue means that you can use the value but you cannot attempt to refer to the memory location where this value might be stored).
The ++ operator updates the value stored in a memory location, therefore it can only be applied to an lvalue. So ++(ptr++) is a constraint violation.
However, * can be applied to rvalues and the result is an lvalue (i.e. an expression that designates a memory location). So ++ can be applied to *ptr++ .
++p++
Says: pre-increment p and post-increment p (in unspecified order). Even if it were allowed it would invoke undefined behavior due to modifying p more than once before encountering a sequence point.
Anyway, the increment operators, post- and pre-, return an rvalue. An rvalue is the value of an expression. It has no location to write to and can be thought as an intermediate value.
*p++
This expression initially results in an lvalue, *p. That location can be written to, so it is incremented by the pre-increment and then p itself is incremented. The increment results in an rvalue, but you are not attempting to modify it.
In C programming preincrement and predecrement operators return an rvalue which essentially tells you that it is a result and not a place to make an assignment. In C++ programming the preincrement and predecrement operators return an lvalue where you can perform further assignments.
A statement like,
int i=10;
++i=5;
is syntactiacally valid in C++. But in C it is a syntax error.
Even in C++ the postincrement and postdecrement operators return an rvalue. Thus the following statement will give you a syntax error in both C and C++.
int i=10;
i++=5;
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Could anyone explain these undefined behaviors (i = i++ + ++i , i = i++, etc…)
#include<stdio.h>
int main()
{
char a[]="Hello";
char *p=a;
while(*p)
++*p++; //Statement 2
printf("%s",a);
int x=10;
++x++; //Statement 1
return 0;
}
When i compile this code i get an l-value Required error in Statement 1, which i can understand. How is that statement 2 does not produce an error even though i intend to do the same thing? Can someone shed light?
Both pre-increment and post-increment produce rvalues and rvalues can't be modified.
So ++x++ (statement 1) is clearly a constraint violation and compiler gives error.
But it's not the case with the statement 2. Though p++ produces an rvalue which its value can't be modified, it can be dereferenced. Alternatively if you do ++p++ this would be equivalent to the ++x++ case and would give an error. Because here the pointer itself is modified.
So it's equivalent to: ++(*p++).
(Note that the brackets are only for understanding and it's not required. The expression ++*p++ is well-defined.)
What happens is:
The post-increment p++ evaluates to the old value of p, in this example &a[0], and the stored value of p is incremented.
*p++ gives the value p pointed to before the increment, in this example a[0].
The final pre-increment increments that value, so a[0] becomes I (probably, could be something else on EBCDIC machines).
When the incremented values of p and a[0] are stored is unspecified, but both must have been stored at the next sequence point (the terminating ;).
Quoting from ISO C99 standard :
6.5.2.4 Postfix increment and decrement operators
Constraints
1
The operand of the postfix increment or decrement operator shall have qualified or
unqualified real or pointer type and shall be a modifiable lvalue.
For this case :
++*p++; //Statement 2
postfix ++ has higher precedence and prefix ++ and * has same precedence and right to left associativity. It means at first step it's incrementing the pointer not it's value.
So it will give you the next address of that type. And then value (which is actually *p) is incremented. So ,In this case no constraint violation.
It's same as ++(*(p++)).
For other case below:
int x=10;
++x++; //Statement 1
In the above case of variable(not pointer) ++(Either postfix or prefix increment or decrement) give you the rvalue ,then applying ++ or -- on rvalue is constraint violation.++ or -- operand should be an lvalue . See the Standard quote written above. Hence giving error.
#include<stdio.h>
int main()
{
char a[]="Hello";
char *p=a;
while(*p)
++*p++; //Statement 2
printf("%s",a);
int x=10;
++x=x++; //Statement 1
return 0;
}
//this code will fetch same error due to the simultaneous pre and post increment.
because it cannot assign and increment simultaneously it require a value to perform increment on it.