what does the error message "Lvalue required" actually mean?
An lvalue is something that can appear on the left side of an assignment, in other words 'something that can be assigned'
So, look for an assignment where the left hand side isn't 'assignable', for example, something as simple as this might trigger such an error
if (0 = foo)
{
}
Here you've got an attempt to assign to a constant because of accidentally using = rather than ==
See also
often used seldom defined terms: lvalue
lvalue and rvalue
“l-value required” error
It means the implementation expects an object, but you just passed a value or function. This happens for assignments you passed a non-lvalue or for address-of operations applied to non-functions.
Lvalue stands for "location value" and means an expression that refers to an object either declared as register or to a memory location. Something like 42 is a value that matches neither criteria. More formally there are three categories
Lvalues: Referring to objects. This includes objects declared const. Such are non-modifiable lvalues.
Function designators: Referring to functions. printf is a function designator, but &printf is not, while *&printf is again.
Others: Sometimes called "rvalue" and by the Standard described as "the value of an expression". Examples are var + 0 (yielding a value not associated with objects anymore), or an enumerator of an enumeration. &printf belongs to this category.
The C99 standard states (6.3.2.1):
An lvalue is an expression with an object type or an incomplete type other than void; 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.
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".
In other words, an lvalue is something that you can locate for potentially changing. A modifiable lvalue is one that you're actually allowed to change.
For example, the C statement:
x = 7;
is valid because x is an lvalue. On the other hand, the statement:
14 = 7;
is not valid because 14 is not something you can locate for an assignment.
The snippet:
const int x = 7;
actually creates an lvalue called x even though you're not permitted to change it (it's not a modifiable `lvalue).
the error cometh if you code somrthing like function(parameter) = value; because you cannot assign value to anything that is not a possible container for it.
Most likely it means that you tried to assign a value to something that cannot be assigned to. For example, both of the following would probably cause that error:
5 = 5;
myObject->myMethod() = 5;
Related
This question already has answers here:
What is the reasoning behind the naming of "lvalue" and "rvalue"?
(6 answers)
Closed 3 years ago.
I've heard the terms lvalue and rvalue come up when working with pointers.
However, I don't fully understand their meaning.
What are lvalues and rvalues?
Note 1: This is a question about C's lvalues and rvalues, not C++'s. It's also about their functionality, not their naming.
Note 2: I already fully understand these concepts. This is meant as a canonical duplicate target.
I've got a longer answer here, but basically C11 draft n1570 6.3.2.1p1:
An lvalue is an expression (with an object type other than void) that potentially designates an object [...]
C11 n1570 Footnote 64:
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. An obvious example of an lvalue is an identifier of an object. As a further example, if E is a unary expression that is a pointer to an object, *E is an lvalue that designates the object to which E points.
Not all lvalues are modifiable, i.e. can appear on the left side of an assignment. Examples of unmodifiable lvalues are those that
have array type,
have incomplete type
are const-qualified
structs or unions that have const-qualified members either directly or recursively
An lvalue can be converted to a value of an expression through lvalue conversion. I.e. in
int a = 0, b = 1;
a = b;
both a and b are lvalues, as they both potentially - and actually - designate objects, but b undergoes lvalue conversion on the right-hand side of the assignment, and the value of the expression b after lvalue conversion is 1.
"Potentially designating an object" means that given int *p;, *p designates an object of type int iff p points to an object of type int - but *p is an lvalue even if p == NULL or indeterminate.
According to the C Reference Manual (3rd Edition):
An lvalue is an expression that refers to an object in such a way that
the object may be examined or altered. Only an lvalue expression may
be used on the left-hand side of an assignment. An expression that is
not an lvalue is sometimes called an rvalue because it can only appear
on the right-hand side of an assignment. An lvalue can have an
incomplete array type, but not void.
This should be pretty obvious, but I could not any normative reference in the Standard explicitly that function call is (not) an lvalue. There is somewhat related question, but it's about C++ and no references is provided.
Looking through 6.5.2.2(p5) Function calls the only I could find is
If the expression that denotes the called function has type pointer to
function returning an object type, the function call expression has the
same type as that object type, and has the value determined as
specified in 6.8.6.4
6.3.2.1(p1) states that
An lvalue is an expression (with an object type other
thanvoid) that potentiallydesignates an object
So I tried to find if a function call designates an object. It is not specified in the Standard if the function call result has storage duration and lifetime. Since any object has storage duration and lifetime I concluded that any function call expression does not designate an object an hence not an lvalue.
But this seems confusing and complicated. In particular I found an example 6.5.2.3(p7):
EXAMPLE 1 If f is a function returning a structure or union, and x is
a member of that structure or union, f().x is a valid postfix
expression but is not an lvalue.
Judging by this example if f() would be an lvalue f().x would also be an lvalue. But examples are informative which made me confused.
It's not an lvalue because its described as a "value" in the paragraph you quoted. The standard explicitly mentions when an expression has the property of being an lvalue. For instance:
6.5.3.2 Address and indirection operators (emphasis mine)
4 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''. If
an invalid value has been assigned to the pointer, the behavior of the
unary * operator is undefined.
As for accessing a union or member. The standard doesn't require the postfix expression in expr.id to be an lvalue. On the contrary. The whole member access has the same value category as the postfix expression:
6.5.2.3 Structure and union members (emphasis mine)
3 A postfix expression followed by the . operator and an identifier
designates a member of a structure or union object. The value is
that of the named member, and is an lvalue if the first expression is
an lvalue. If the first expression has qualified type, the result
has the so-qualified version of the type of the designated member.
So in the example you quoted, f().x is a value, and not an lvalue, because f() itself is not an lvalue.
The return value of a function is not an lvalue as the Standard defines the term, but there are contexts where it would offer the semantics of one.
Given any structure type:
struct foo {...whatever... };
one can write a function whose return value can be used in ways that would require an lvalue of type struct foo [most typically passing the address of such an lvalue to another function].
struct wrapped_foo {struct foo it[1];} wrap_foo(foo it)
{
struct wrapped_foo ret = {it};
return ret;
}
extern void do_something(int,int,int,struct foo const *p,int,int,int);
void demo_of_passing_address_of_a_foo(struct foo x)
{
do_something(1,2,3,&(wrap_foo(x).it[0]),4,5,6);
}
Note that while the return value of wrap_foo(x) isn't an lvalue, wrap_foo(x).it[0] is one, and its address can be taken. The lifetime of the object identified thereby will extend through the evaluation of the enclosing expression, i.e. the call to do_something. If the subscripting operator were defined in its own right as an operator which does not result in array-to-pointer decomposition but simply yields a value of the element type, which would be an lvalue only when the array was one, then wrap_foo(x).it[0] would not be an lvalue, and issues of lifetime would be irrelevant.
While the ability to pass the address of a temporary is useful, it adds compiler complexity by requiring that a compiler given something like the above allocate space for wrap_foo's return value before stacking any of the arguments to the outer function call. If such compiler complexity is required, it could just as well allow such semantics to be achieved by allowing top-level argument expressions to use & on values of arbitrary type (yielding a const-qualified pointer to an object whose lifetime would be that of the outer enclosing expression).
Code sample:
struct name
{
int a, b;
};
int main()
{
&(((struct name *)NULL)->b);
}
Does this cause undefined behaviour? We could debate whether it "dereferences null", however C11 doesn't define the term "dereference".
6.5.3.2/4 clearly says that using * on a null pointer causes undefined behaviour; however it doesn't say the same for -> and also it does not define a -> b as being (*a).b ; it has separate definitions for each operator.
The semantics of -> in 6.5.2.3/4 says:
A postfix expression followed by the -> operator and an identifier designates a member
of a structure or union object. The value is that of the named member of the object to
which the first expression points, and is an lvalue.
However, NULL does not point to an object, so the second sentence seems underspecified.
Also relevant might be 6.5.3.2/1:
Constraints:
The operand of the unary & operator shall be either a function designator, the result of a
[] or unary * operator, or an lvalue that designates an object that is not a bit-field and is
not declared with the register storage-class specifier.
However I feel that the bolded text is defective and should read lvalue that potentially designates an object , as per 6.3.2.1/1 (definition of lvalue) -- C99 messed up the definition of lvalue, so C11 had to rewrite it and perhaps this section got missed.
6.3.2.1/1 does say:
An lvalue is an expression (with an object type other than void) that potentially
designates an object; if an lvalue does not designate an object when it is evaluated, the
behavior is undefined
however the & operator does evaluate its operand. (It doesn't access the stored value but that is different).
This long chain of reasoning seems to suggest that the code causes UB however it is fairly tenuous and it's not clear to me what the writers of the Standard intended. If in fact they intended anything, rather than leaving it up to us to debate :)
From a lawyer point of view, the expression &(((struct name *)NULL)->b); should lead to UB, since you could not find a path in which there would be no UB. IMHO the root cause is that at a moment you apply the -> operator on an expression that does not point to an object.
From a compiler point of view, assuming the compiler programmer was not overcomplicated, it is clear that the expression returns the same value as offsetof(name, b) would, and I'm pretty sure that provided it is compiled without error any existing compiler will give that result.
As written, we could not blame a compiler that would note that in the inner part you use operator -> on an expression than cannot point to an object (since it is null) and issue a warning or an error.
My conclusion is that until there is a special paragraph saying that provided it is only to take its address it is legal do dereference a null pointer, this expression is not legal C.
Yes, this use of -> has undefined behavior in the direct sense of the English term undefined.
The behavior is only defined if the first expression points to an object and not defined (=undefined) otherwise. In general you shouldn't search more in the term undefined, it means just that: the standard doesn't provide a meaning for your code. (Sometimes it points explicitly to such situations that it doesn't define, but this doesn't change the general meaning of the term.)
This is a slackness that is introduced to help compiler builders to deal with things. They may defined a behavior, even for the code that you are presenting. In particular, for a compiler implementation it is perfectly fine to use such code or similar for the offsetof macro. Making this code a constraint violation would block that path for compiler implementations.
Let's start with the indirection operator *:
6.5.3.2 p4:
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". If an
invalid value has been assigned to the pointer, the behavior of the unary * operator is
undefined. 102)
*E, where E is a null pointer, is undefined behavior.
There is a footnote that states:
102) Thus, &*E is equivalent to E (even if E is a null pointer), and &(E1[E2]) to ((E1)+(E2)). It is
always true that if E is a function designator or an lvalue that is a valid operand of the unary &
operator, *&E is a function designator or an lvalue equal to E. If *P is an lvalue and T is the name of
an object pointer type, *(T)P is an lvalue that has a type compatible with that to which T points.
Which means that &*E, where E is NULL, is defined, but the question is whether the same is true for &(*E).m, where E is a null pointer and its type is a struct that has a member m?
C Standard doesn't define that behavior.
If it were defined, new problems would arise, one of which is listed below. C Standard is correct to keep it undefined, and provides a macro offsetof that handles the problem internally.
6.3.2.3 Pointers
An integer constant expression with the value 0, or such an expression cast to type
void *, is called a null pointer constant. 66) If a null pointer constant is converted to a
pointer type, the resulting pointer, called a null pointer, is guaranteed to compare unequal
to a pointer to any object or function.
This means that an integer constant expression with the value 0 is converted to a null pointer constant.
But the value of a null pointer constant is not defined as 0. The value is implementation defined.
7.19 Common definitions
The macros are
NULL
which expands to an implementation-defined null pointer constant
This means C allows an implementation where the null pointer will have a value where all bits are set and using member access on that value will result in an overflow which is undefined behavior
Another problem is how do you evaluate &(*E).m? Do the brackets apply and is * evaluated first. Keeping it undefined solves this problem.
First, let's establish that we need a pointer to an object:
6.5.2.3 Structure and union members
4 A postfix expression followed by the -> operator and an identifier designates a member
of a structure or union object. The value is that of the named member of the object to
which the first expression points, and is an lvalue.96) If the first expression is a pointer to
a qualified type, the result has the so-qualified version of the type of the designated
member.
Unfortunately, no null pointer ever points to an object.
6.3.2.3 Pointers
3 An integer constant expression with the value 0, or such an expression cast to type
void *, is called a null pointer constant.66) If a null pointer constant is converted to a
pointer type, the resulting pointer, called a null pointer, is guaranteed to compare unequal
to a pointer to any object or function.
Result: Undefined Behavior.
As a side-note, some other things to chew over:
6.3.2.3 Pointers
4 Conversion of a null pointer to another pointer type yields a null pointer of that type.
Any two null pointers shall compare equal.
5 An integer may be converted to any pointer type. Except as previously specified, the
result is implementation-defined, might not be correctly aligned, might not point to an
entity of the referenced type, and might be a trap representation.67)
6 Any pointer type may be converted to an integer type. Except as previously specified, the
result is implementation-defined. If the result cannot be represented in the integer type,
the behavior is undefined. The result need not be in the range of values of any integer
type.
67) The mapping functions for converting a pointer to an integer or an integer to a pointer are intended to be consistent with the addressing structure of the execution environment.
So even if the UB should happen to be benign this time, it might still result in some totally unexpected number.
Nothing in the C standard would impose any requirements on what a system could do with the expression. It would, when the standard was written, have been perfectly reasonable for it to to cause the following sequence of events at runtime:
Code loads a null pointer into the addressing unit
Code asks the addressing unit to add the offset of field b.
The addressing unit trigger a trap when attempting to add an integer to a null pointer (which should for robustness be a run-time trap, even though many systems don't catch it)
The system starts executing essentially random code after being dispatched through a trap vector that was never set because code to set it would have wasted been a waste of memory, as addressing traps shouldn't occur.
The very essence of what Undefined Behavior meant at the time.
Note that most of the compilers that have appeared since the early days of C would regard the address of a member of an object located at a constant address as being a compile-time constant, but I don't think such behavior was mandated then, nor has anything been added to the standard which would mandate that compile-time address calculations involving null pointers be defined in cases where run-time calculations would not.
No. Let's take this apart:
&(((struct name *)NULL)->b);
is the same as:
struct name * ptr = NULL;
&(ptr->b);
The first line is obviously valid and well defined.
In the second line, we calculate the address of a field relative to the address 0x0 which is perfectly legal as well. The Amiga, for example, had the pointer to the kernel in the address 0x4. So you could use a method like this to call kernel functions.
In fact, the same approach is used on the C macro offsetof (wikipedia):
#define offsetof(st, m) ((size_t)(&((st *)0)->m))
So the confusion here revolves around the fact that NULL pointers are scary. But from a compiler and standard point of view, the expression is legal in C (C++ is a different beast since you can overload the & operator).
At C99§6.5.2.2p5 there's this little gem, bolded by me for the purpose of emphasizing the question:
If the expression that denotes the called function has type pointer to function returning an object type, the function call expression has the same type as that object type, and has the value determined as specified in 6.8.6.4. Otherwise, the function call has type void. If an attempt is made to modify the result of a function call or to access it after the next sequence point, the behavior is undefined.
This allowed us to return structs, for example:
struct foo { int foo;
char bar[2]; };
struct foo get_foo() {
struct foo return_value = { .foo = 42,
.bar = "x" };
return return_value;
}
... and assign that return value somewhere else from within the caller, for example:
int main(void) {
struct foo bar = get_foo(); /* Well defined because the return value
* is copied -before- the sequence point
* that terminates its storage duration */
printf("%s\n", bar.bar);
printf("%d\n", get_foo().foo); /* Again, well defined because the access
* occurs before the next sequence point
* (the function call). */
}
... whilst rendering examples like the following invalid:
int main(void) {
printf("%s\n", get_foo().bar); /* UB because there's a sequence point
* between the evaluation of the sub-
* expression `get_foo().bar` and the
* entrace to the function `printf` */
get_foo().bar[0]++; /* UB because an attempt is made to modify the
* result of a function call */
}
--
C11§6.5.2.2p5, however, is essentially the same paragraph but without the bolded text.
If the expression that denotes the called function has type pointer to function returning an object type, the function call expression has the same type as that object type, and has the value determined as specified in 6.8.6.4. Otherwise, the function call has type void.
Are those examples above that are undefined behaviour in C99 still undefined in C11? If so, which paragraphs invalidate them? If not, I gather there must be some extension of the storage duration of automatic values/objects returned; which section of the standard specifies that extension of storage duration?
Are those examples above that are undefined behaviour in C99 still undefined in C11?
The examples posed above that are well defined are still well defined.
The temporary lifetime of the object in this one "ends when the evaluation of the containing full expression or declarator ends", so this previously undefined example is now well defined:
printf("%s\n", get_foo().bar);
This example is still undefined behaviour, because an attempt is made to modify an object that has temporary lifetime:
get_foo().bar[0]++;
If so, which paragraphs invalidate them? If not, I gather there must be some extension of the storage duration of automatic values/objects returned; which section of the standard specifies that extension of storage duration?
As pointed out by Jens Gustedt in a comment, C11§6.2.4p8 seems to convey a slightly different meaning to the sentence that C99§6.5.2.2p5 contains which C11§6.5.2.2p5 omitted:
A non-lvalue expression with structure or union type, where the structure or union contains a member with array type (including, recursively, members of all contained structures and unions) refers to an object with automatic storage duration and temporary lifetime.36) Its lifetime begins when the expression is evaluated and its initial value is the value of the expression. Its lifetime ends when the evaluation of the containing full expression or full declarator ends. Any attempt to modify an object with temporary lifetime results in undefined behavior.
36) The address of such an object is taken implicitly when an array member is accessed.
It seems that a little reorganisation was performed; the "storage duration extension" sentence in C99 was changed and moved from the "function call" section to the "storage duration" section, where it fits better.
The only question remaining is whether or not the result of a function call is considered an lvalue. For every operator that produces an lvalue, it seems as though it is explicitly mentioned that the operator produces an lvalue. For example, C11§6.5.3.2p6 states that the unary * operator produces an lvalue providing its operand points at an object.
The function call operator, however, says nothing about producing an lvalue, so we must assume that it doesn't produce an lvalue. If that's not good enough, then consider C11§6.5.2.3p3 and p7, which say:
A postfix expression followed by the . operator and an identifier designates a member of a structure or union object. The value is that of the named member,95) and is an lvalue if the first expression is an lvalue.
If f is a function returning a structure or union, and x is a member of that structure or union, f().x is a valid postfix expression but is not an lvalue.
We can also deduce from these two paragraphs that the result of a function is not an lvalue, thus meeting the criteria for C11§6.2.4p8 (quoted above).
Footnote 95 is interesting but tangential to the discussion on hand:
95) If the member used to read the contents of a union object is not the same as the member last used to
store a value in the object, the appropriate part of the object representation of the value is reinterpreted
as an object representation in the new type as described in 6.2.6 (a process sometimes called ‘‘type
punning’’). This might be a trap representation.
Just wonder if a literal string is an lvalue or an rvalue. Are other literals (like int, float, char etc) lvalue or rvalue?
Is the return value of a function an lvalue or rvalue?
How do you tell the difference?
string literals are lvalues, but you can't change them
rvalue, but if it's a pointer and non-NULL, the object it points to is an lvalue
The C standard recognizes the original terms stood for left and right as in L = R; however, it says to think of lvalue as locator value, which roughly means you can get the address of an object and therefore that object has a location. (See 6.3.2.1 in C99.)
By the same token, the standard has abandoned the term rvalue, and just uses "the value of an expression", which is practically everything, including literals such as ints, chars, floats, etc. Additionally, anything you can do with an rvalue can be done with an lvalue too, so you can think of all lvalues as being rvalues.
There are two kinds of expressions in C:
1. lvalue: An expression that is an lvalue may appear as either the left-hand or right-hand side of an assignment.
2. rvalue: An expression that is an rvalue may appear on the right- but not left-hand side of an assignment.
Variables are lvalues and so may appear on the left-hand side of an assignment. Numeric literals are rvalues and so may not be assigned and cannot appear on the left-hand side. Following is a valid statement:
int g = 20;
But following is not a valid statement and would generate compile-time error:
10=20;
there's a definition for C++ from Microsoft. By this definition,
a literal string, say "hello world", is lvalue, because it's const and not temporary. Actually it persists across your application's lifetime.