int *p=&a++ and int *p=&++a - c

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.

Related

Why It throws an error lvalue is required?

#include<stdio.h>
int main(){
int i=0,j=1;
printf("%d",++(i+j));
return 0;
}
In this code I have used the increment operator but i don't know why it throws an error.
It throws the error:
lvalue is required.
You are trying to increment an integer value that isn't assigned to a variable.
Taking your code, this is approximately what the computer will try to do:
printf("%d",++(i+j));
// expanded step 1
printf("%d",++(0+1));
// expanded step 2
printf("%d",++(1));
As you can see in the last version, you are trying to call ++1, which is invalid.
In order to increment a value using ++, the operand must have integral, floating, or pointer type and must be a modifiable l-value expression (an expression without the const attribute):
int x = i+j;
printf("%d",++x);
Alternatively, you can use the addition operator:
printf("%d",i+j+1);
You cant increment the result.
Instead:
printf("%d",i + j + 1);
In C you cannot apply an unary operator too a number. When the value between the parentesis is evaluated first... before use the unary operation. assing the result to a variable.
#include<stdio.h>
int main(){
int i=0,j=1, other_value=0;
other_value = i+j;
printf("%d",++(other_value));
return 0;
}
Your previus code will work will get the error
error: lvalue required as increment operand
An "lvalue" is a value that can be the target of an assignment. The "l" stands for "left", as in the left hand side of the equals sign. An rvalue is the right hand value and produces a value, and cannot be assigned to directly. If you are getting "lvalue required" you have an expression that produces an rvalue when an lvalue is required.
in your case when compiler manipulate the expression then it will result to invalid expression which is ++1
try below:
printf("%d",i+j+1);
The expression ++(i+j) is not assignable. Here, the expression (i+j) will get evaluated first. For the ++ operator, the operand must have integral, floating, or pointer type and must be a modifiable l-value expression. Since the result from i+j is a constant value, so you get the error lvalue required as increment operand. You can choose to modify this expression as i+j+1.

Why can't you increment/decrement a variable twice in the same expression?

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;

what are l-value and r-value expression?

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;

Condition for lvalues and rvalues in C

Here are the few definitions I read about lvalues
Expressions which can be used with & operator. i.e if &(expression) is not an error, then the expression is an lvalue
Expression which results in objects that are not temporary
lvalue expressions can be used on both RHS and LHS of = operator
rvalue expressions can be used only on RHS
Please correct if wrong
Here's the question
I read ++x is a lvalue and x++ is an rvalue
int i = 0;
printf("%p",(void*)&++i);
If so, why is this an error?
If lvalue expressions can be used on lhs
int i = 0;
++i = 10;
Why can't I use the above statement??Both the above are resulting in errors
Update: Both the above statements are fine in C++
Neither ++i nor i++ are lvalues.
You might be thinking about *x++ and *++x which are both lvalues (if x has a pointer type).
++i is an lvalue only in C++, in C it's an rvalue (called value of an expression in the C standard) which cannot be assigned.
I thought that this question would be closed, and I only left a comment. What a big mistake;)
In C (the question's tag is C) ++i operator does "return" a value, but not the variable itself. Hence it's address can not be retrieved. In other words ++i is not an lvalue. Neither is i++.
C++ is may be different from C in regard of certain constructs being l- and r-values.
http://eli.thegreenplace.net/2011/12/15/understanding-lvalues-and-rvalues-in-c-and-c/
For C++ these two are lvalues.
This simple code:
#include <stdio.h>
int main() {
int i=0;
++i = 10;
printf("\n%d\n", i);
++i = ++i;
printf("%d\n", i);
}
Compiled with gcc will give:
lvalue.c:3: error: invalid lvalue in assignment
lvalue.c:4: warning: incompatible implicit declaration of built-in function ‘printf’
lvalue.c:5: error: invalid lvalue in assignment
and for g++ compiles correctly and yelds:
10
12
The (rather vague) formal definition from C11:
(emphasis in bold font was added by me)
6.3.2.1 Lvalues, arrays, and function designators
An lvalue is an expression (with an object type other than void) that potentially designates an object (64); if an lvalue does not designate an object when it is evaluated, the behavior is undefined. When an object is said to have a particular type, the type is specified by the lvalue used to designate the object. A modifiable lvalue is an lvalue that does not have array type, does not have an incomplete type, does not have a const-qualified type, and if it is a structure or union, does not have any member (including, recursively, any member or element of all contained aggregates or unions) with a const-qualified type.
Foot note (not normative) with further explanation:
64) The name "lvalue" comes originally from the assignment expression E1 = E2, in which the left operand E1 is required to be a (modifiable) lvalue. It is perhaps better considered as representing an object "locator value". What is sometimes called "rvalue" is in this International Standard described as the "value of an expression".
So an lvalue must be something that "potentially" designates an object. Whatever "potentially" means is open for personal interpretation...
Despite the above foot note, the C standard lacks a formal definition of a rvalue. Ironically, the only place in the whole standard mentioning rvalue is that one foot note.
In your case, neither ++i nor i++ designates an actual object, so neither of them are lvalues. They are rather rvalues.
By making ++i an lvalue, imagine that you can now do:
int i=2;
++i = ++i;
Apart from nasal daemons, what would you like i to look like afterwards? 4? 3?

Explanation of ++val++ and ++*p++ in C

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.

Resources