Lvalue Required As Left Operand Of Assignment Array Technologies

In this tutorial you will know about one of the most occurred error in C and C++ programming, i.e. lvalue required as left operand of assignment.

lvalue means left side value. Particularly it is left side value of an assignment operator.

rvalue means right side value. Particularly it is right side value or expression of an assignment operator.

Example:

In above example is lvalue and b + 5 is rvalue.

In C language lvalue appears mainly at four cases as mentioned below:

  1. Left of assignment operator.
  2. Left of member access (dot) operator (for structure and unions).
  3. Right of address-of operator (except for register and bit field lvalue).
  4. As operand to pre/post increment or decrement for integer lvalues including Boolean and enums.

Solve error: lvalue required as left operand of assignment

Now let see some cases where this error occur with code.

Example 1:

When you will try to run above code, you will get following error.

Solution: In if condition change assignment operator to comparison operator, as shown below.

Example 2:

Above code will show the error: lvalue required as left operand of assignment operator.

Here problem occurred due to wrong handling of short hand operator (*=) in findFact() function.

Solution: Just by changing the line ans*i=ans to ans*=i we can avoid that error. Here short hand operator expands like this, ans=ans*i. Here left side some variable is there to store result. But in our program ans*i is at left hand side. It’s an expression which produces some result. While using assignment operator we can’t use an expression as lvalue.

The correct code is shown below.

Example 3:

Above code will show the same lvalue required error.

Reason and Solution: Ternary operator produces some result, it never assign values inside operation. It is same as a function which has return type. So there should be something to be assigned but unlike inside operator.

The correct code is given below.

Some Precautions To Avoid This Error

There are no particular precautions for this. Just look into your code where problem occurred, like some above cases and modify the code according to that.

Mostly 90% of this error occurs when we do mistake in comparison and assignment operations. When using pointers also we should careful about this error. And there are some rare reasons like short hand operators and ternary operators like above mentioned. We can easily rectify this error by finding the line number in compiler, where it shows error: lvalue required as left operand of assignment.

Comment below if you have any queries related to above tutorial.


#include<stdio.h>

 

intmain(){

    inta=5,b=5;

 

    if(a%b=0)

        printf("its crazy");

 

    return0;

}

#include<stdio.h>

 

intmain(){

    inta=5,b=5;

 

    if(a%b==0)

        printf("its crazy");

 

    return0;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

#include<stdio.h>

 

intfindFact(intn){

    intans=1,i;

    

    for(i=1;i<=n;i++){

        ans*i=ans;

    }

 

    returnans;

}

 

intmain(){

    intn=5;

    intfact=findFact(n);

    printf("%d",fact);

 

    return0;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

#include<stdio.h>

 

intfindFact(intn){

    intans=1,i;

    

    for(i=1;i<=n;i++){

        ans*=i;

    }

 

    returnans;

}

 

intmain(){

    intn=5;

    intfact=findFact(n);

    printf("%d",fact);

 

    return0;

}

// misunderstanding ternary operator

#include<stdio.h>

 

intmain(){

    inta=5,b;

 

    a>=5?b=10:b=19;

 

    return0;

}

#include<stdio.h>

 

intmain(){

    inta=5,b;

 

    b=a>=5?10:19;

 

    return0;

}

Category: C Tutorials

Ubuntu Forums > The Ubuntu Forum Community > Ubuntu Specialised Support > Development & Programming > Programming Talk > lvalue required error???


PDA

View Full Version : lvalue required error???



Praveen30

January 27th, 2011, 07:57 AM

#include<stdio.h>

void main()
{
char arr[8]="rhombus";
int i;
for(i=0;i<=7;i++)
printf("\n%d",*arr);
arr++; //lvalue required here//
}

i am getting an error..LVALUE required...i want to know deeply what is this lvalue...why it comes??how it comes??

i can run this programme by putting *(arr+i) in place of *arr..and omitting arr++..but this is not my point of concern....


dileepm

January 27th, 2011, 08:09 AM

Can u try changing your code to


#include<stdio.h>

void main()
{
char arr[7]="rhombus";
int i;
for(i=0;i<7;i++)
printf("\n%d",arr[i]);
i++;
}


MadCow108

January 27th, 2011, 09:07 AM

an lvalue is a reference to an object where something can be stored in. e.g. a piece of memory.
They can be modifiable or not.

an array is no modifiable lvalue you can't assign a different memory location to it after initialization.
you can use a pointer to the beginning of the array to do what you wanted:


int ar[]={1,2,3};
int * p = ar; // implicit conversion of array to pointer
for (int i=0; i< 3; i++) {
printf("%d\n",*p);
p++; // can be assigned to
}
// or
for (int * p = ar; p < ar + 3; p++)
printf("%d\n",*p);


Praveen30

January 27th, 2011, 09:35 AM

an lvalue is a reference to an object where something can be stored in. e.g. a piece of memory.
They can be modifiable or not.

an array is no modifiable lvalue you can't assign a different memory location to it after initialization.
you can use a pointer to the beginning of the array to do what you wanted:


int ar[]={1,2,3};
int * p = ar; // implicit conversion of array to pointer
for (int i=0; i< 3; i++) {
printf("%d\n",*p);
p++; // can be assigned to
}
// or
for (int * p = ar; p < ar + 3; p++)
printf("%d\n",*p);


ok fine, but can you tell me what are the different possibilities where lvalue error can come???


Tony Flury

January 27th, 2011, 10:50 AM

ok fine, but can you tell me what are the different possibilities where lvalue error can come???

@Praveen30 - MadCow108 did already explain it "an lvalue is a reference to an object where something can be stored in. e.g. a piece of memory. They can be modifiable or not."

In other words - an Lvalue is any object/variable that can appear on the left hand side of an assignment - hence LValue (Left Value).

given the declarations you have - you could not do :


arr = 3 ;

for instance as you can't change the value of arr - It is not a valid lvalue.

You could do


arr[0] = 3 ;


MadCow108

January 27th, 2011, 11:01 AM

another example for the lvalue error is:


1 = 3;

>lvalue required as left operand of assignment

a number is nothing where something can be stored, it is no lvalue. (in C at least, I think there are languages which allow this [fortran?] ).


Praveen30

January 27th, 2011, 02:48 PM

another example for the lvalue error is:


1 = 3;

>lvalue required as left operand of assignment
a number is nothing where something can be stored, it is no lvalue. (in C at least, I think there are languages which allow this [fortran?] ).

thanks!!!!!


psusi

January 27th, 2011, 03:31 PM

Actually if something can not be modified then by definition, it is NOT an lvalue. Things that can be modified can be used as either rvalue or lvalue, but immutable objects can only be used as rvalues.


Praveen30

January 27th, 2011, 03:50 PM

Actually if something can not be modified then by definition, it is NOT an lvalue. Things that can be modified can be used as either rvalue or lvalue, but immutable objects can only be used as rvalues.

thanks for clarifying this!!!!


trent.josephsen

January 27th, 2011, 05:13 PM

C99 6.3.2.1 says (formatting in the original):


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. [...] 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.

Except when it is the operand of the sizeof operator, the unary & operator, the ++ operator, the -- operator, or the left operand of the . operator or an assignment operator, an lvalue that does not have array type is converted to the value stored in the designated type (and is no longer an lvalue). [...]

Except when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array, an expression that has the type "array of type" is converted to an expression with type "pointer to type" that points to the initial element of the array object and is not an lvalue.

In the attempted assignment

1 = 3;1 is merely a value and does not designate an object; therefore trying to use it as an lvalue results in undefined behavior. If you were foolish or curious enough to try it, you may expect demons to fly out of your nose.

In the attempted postincrement

arr++;"arr" is converted to an expression that is not an lvalue, according to the third paragraph quoted above. Since 6.5.2.4p1 requires that the operand of ++ be a modifiable lvalue, that line contains a constraint violation requiring a diagnostic. When a diagnostic has been issued, then the nasal demons may appear.

So, to be extremely nitpicky: lvalues may be modifiable or not, but what you have is a non-lvalue by virtue of conversion to pointer, not just an unmodifiable lvalue. That is why you got a message saying "lvalue required" despite the fact that "arr" is in fact an lvalue.


psusi

January 27th, 2011, 05:38 PM

In the attempted assignment

1 = 3;1 is merely a value and does not designate an object; therefore trying to use it as an lvalue results in undefined behavior. If you were foolish or curious enough to try it, you may expect demons to fly out of your nose.

No, the behavior is quite well defined: the program is malformed and the compiler errors out.


So, to be extremely nitpicky: lvalues may be modifiable or not, but what you have is a non-lvalue by virtue of conversion to pointer, not just an unmodifiable lvalue. That is why you got a message saying "lvalue required" despite the fact that "arr" is in fact an lvalue.

It does not make sense to say that something is both non modifiable, and can be used as an lvalue. Either you can use it on the left side of an assignment or you can't.

Arrays are not lvalues. You seem to be arguing that the array starts out as an lvalue, then implicitly is converted to an rvalue. For that to be true, there has to be a circumstance where that conversion does not happen and you can use the array as an lvalue.


Arndt

January 27th, 2011, 05:47 PM

No, the behavior is quite well defined: the program is malformed and the compiler errors out.



It does not make sense to say that something is both non modifiable, and can be used as an lvalue. Either you can use it on the left side of an assignment or you can't.

Arrays are not lvalues. You seem to be arguing that the array starts out as an lvalue, then implicitly is converted to an rvalue. For that to be true, there has to be a circumstance where that conversion does not happen and you can use the array as an lvalue.

Are there not enough clues in the standard text that was quoted?

"An lvalue is an expression with an object type or an incomplete type other than void;"

" A modifiable lvalue is an lvalue that does not have array type"

"Except when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array, an expression that has the type "array of type"..."

sizeof is the answer to your question.


Does the phrase "use as an lvalue" occur in the standard at all?


psusi

January 27th, 2011, 07:22 PM

sizeof is the answer to your question.


sizeof does not require an lvalue.

I guess you can say that it is an lvalue because you can't tell the difference, in the same sense that Schroedinger's cat is both alive and dead, but most people don't like to think that way. Most people recognize that you can't be both alive and dead, and you aren't both an rvalue and an lvalue, so an array is an rvalue since it can't be used where an lvalue is required.


worksofcraft

January 27th, 2011, 08:21 PM

Sigh - I have this sinking feeling I've posted this link before about lvalues (http://en.wikipedia.org/wiki/Value_(computer_science))

I will try to put it in my own words:


An lvalue is something that has been allocated memory space at run time. To access it, the computer instructions will use a memory address.

A non-lvalue is something that does not have a designated memory space at run time. The computer will not use a memory address to retrieve it's value and it can't write a new value to it.

Example of a non-lvalue is in an increment instruction that adds the value "one" to it's destination. It does not need to go fetch that value of "one" from anywhere else in memory as it is part of the actual code that is executing.

WRT to this thread, An array IS an lvalue because it resides at a certain location in memory at run time.
OTOH the address of that array is not an lvalue: It will be built into the instructions that access the array.
In C the name of an array is synonymous with the address of that array and so it is not an lvalue that you could increment.
If you want to make it into an lvalue then you need to store it in a pointer variable. Said pointer then does have a memory address of it's own at run time...


Arndt

January 27th, 2011, 10:48 PM

C99 6.3.2.1 says (formatting in the original):



In the attempted assignment

1 = 3;1 is merely a value and does not designate an object; therefore trying to use it as an lvalue results in undefined behavior. If you were foolish or curious enough to try it, you may expect demons to fly out of your nose.

In the attempted postincrement

arr++;"arr" is converted to an expression that is not an lvalue, according to the third paragraph quoted above. Since 6.5.2.4p1 requires that the operand of ++ be a modifiable lvalue, that line contains a constraint violation requiring a diagnostic. When a diagnostic has been issued, then the nasal demons may appear.

So, to be extremely nitpicky: lvalues may be modifiable or not, but what you have is a non-lvalue by virtue of conversion to pointer, not just an unmodifiable lvalue. That is why you got a message saying "lvalue required" despite the fact that "arr" is in fact an lvalue.

I found this to be somewhat illuminating. I wasn't even aware that the formulation had changed: http://bytes.com/topic/c/answers/559645-lvalue-modifiable-non-modifiable


Praveen30

January 28th, 2011, 03:36 AM

Sigh - I have this sinking feeling I've posted this link before about lvalues (http://en.wikipedia.org/wiki/Value_%28computer_science%29)

I will try to put it in my own words:


An lvalue is something that has been allocated memory space at run time. To access it, the computer instructions will use a memory address.
A non-lvalue is something that does not have a designated memory space at run time. The computer will not use a memory address to retrieve it's value and it can't write a new value to it.

Example of a non-lvalue is in an increment instruction that adds the value "one" to it's destination. It does not need to go fetch that value of "one" from anywhere else in memory as it is part of the actual code that is executing.

WRT to this thread, An array IS an lvalue because it resides at a certain location in memory at run time.
OTOH the address of that array is not an lvalue: It will be built into the instructions that access the array.
In C the name of an array is synonymous with the address of that array and so it is not an lvalue that you could increment.
If you want to make it into an lvalue then you need to store it in a pointer variable. Said pointer then does have a memory address of it's own at run time...
nice one, Sir.


psusi

January 28th, 2011, 03:57 AM

You can look at it that way. Or you can look at it as the elements of the array are lvalues, but the array as a whole is not, and the array as a whole will decay into a pointer to the first element, which is itself not an lvalue, but when you dereference it to get to the first element, that is an lvalue.


trent.josephsen

January 28th, 2011, 11:16 PM

For the record.


Actually if something can not be modified then by definition, it is NOT an lvalue.

This is one possible definition of "lvalue". I don't want to imply that this definition is incorrect. However, in relation to C, it might be misleading to use this definition, because the C Standard uses the term differently (and is defined as I quoted in my previous post).

array, constant, and object also come to mind as words that have a particular well-defined and specific meaning in the Standard, but are often used in a different sense elsewhere. (Whether the Standard is in error for co-opting these or any other terms to describe the C language is neither relevant nor topical, and I hope we don't get into that.)

In my first post, I was trying to reconcile the compiler's error message with the Standard. Reading it with the conventional meaning of "lvalue" results in psusi's interpretation, which is (strictly speaking) incorrect according to the Standard, but as for what is actually going on inside the compiler to detect the error, who knows? The important part is that the compiler correctly issues a diagnostic (it's a constraint violation, after all).

Aside:

Does the phrase "use as an lvalue" occur in the standard at all?
No. What I meant to say is something like this:
1 either is an lvalue or is not. If it is, then since it does not designate an object, the behavior is undefined. If it is not, then the construction violates 6.5.16p2, which says that an assignment operator shall have a modifiable lvalue as its left operand.

Interestingly enough, it seems that it would be OK for a C implementation to allow integer constants to be lvalues (even modifiable lvalues). I doubt any implementation has taken advantage of this, and I can't think of any practical application that wouldn't be better done some other way, but there you go.


dribeas

January 29th, 2011, 01:35 AM

Arrays are some particular beasts in the language. The rules that apply to the rest of the types do not apply to arrays by design. The first of those rules is about the pass-by-value syntax you don't get pass-by-value semantics. To make this happen, the language was tweaked so that arrays decay into pointers to the first element in most contexts, the decayed pointer is an rvalue. This has generated a big amount of confusion with many people (including book authors) stating that arrays are pointers and such.

On the other hand, another quite common misunderstanding is that a given object is an lvalue or rvalue, that is wrong. Expressions are lvalues or rvalues, not variables. In general, unless the expression in which is used requires a conversion and as such it produces an rvalue, any identifier for a variable represents an lvalue expression.

Now, the fact that in most use cases the language forces the decay to a pointer to the first element for arrays, and that that the result of the decay is an rvalue expression, does not mean that the identifier of the array is an rvalue expression. For a counter example, the language requires that the argument to the operator & has to be either the result of a [], unary * operator or an lvalue that is not a bitfield. Now, while this is not the same as a real proof, a simple test that verifies the lvalue-ness of an array can be done with this simple program:



int main() {
int array[10];
int (*p)[10] = &array; // this requires array to be an lvalue
}


On some of the comments above that say that if it is not modifiable it is not an lvalue, the same goes: lvalue-ness is unrelated to const-ness. Const-ness can be used to create expressions that generate unmodifiable lvalues as for example in:



int main() {
const int constant = 10;
const int * p = &constant; // same stupid test as above
}


Which is a simple proof that you can actually have non modifiable lvalue expressions.

Another trivial proof for the two things above is a single sentence from the standard quoted above: A modifiable lvalue is an lvalue that does not have array type If an lvalue could never be non-modifiable there would not be any need to define what a modifiable lvalue is. If an lvalue could not have array type, there would not be any need to state that a modifiable lvalue (subset of lvalue) cannot have array type...

Whenever in doubt, read @worksofcraft post above: lvalue-ness of an expression has more to do with the posibility of taking it's address than any other thing


psusi

January 29th, 2011, 05:04 AM

How does that require array to be an lvalue when it is on the right hand side of the assignment, not the left?

And just because they used the word modifiable lvalue does not necessarily mean there is such a thing as a non modifiable lvalue.


worksofcraft

January 29th, 2011, 06:04 AM

And just because they used the word modifiable lvalue does not necessarily mean there is such a thing as a non modifiable lvalue.
OK well you hopefully will agree that a const int is non-modifiable?


// g++ modifiable.cpp
#include <cstdio>
const int nonModifiableLValue = 57005;
int main() {
return !printf("nonModifiableLValue=%x at %p\n",
nonModifiableLValue,
& nonModifiableLValue
);
}




$ g++ -Wall modifiable.cpp
$ ./a.out
nonModifiableLValue=dead at 0x40074c


Compiles and runs... so it is not modifiable but is it an lvalue?



// g++ modifiable.cpp
#include <cstdio>
enum { nonModifiableLValue = 57005 };
int main() {
return !printf("nonModifiableLValue=%x at %p\n",
nonModifiableLValue,
& nonModifiableLValue
);
}




$ g++ -Wall modifiable.cpp
modifiable.cpp: In function ‘int main(int, char**, char**)’:
modifiable.cpp:7: error: lvalue required as unary ‘&’ operand


Evidently the enum is NOT an lvalue and so the compiler flatly refuses to take it's address. :shock:

In that case the cost int must have been an lvalue and in being const it isn't modifiable ;)


worksofcraft

January 29th, 2011, 06:24 AM

p.s.

Just as a trick question... see if you can predict whether the compiler should cope with this one:


// g++ modifiable.cpp
#include <cstdio>
const int & value(const int &input) { return input; }
#define nonModifiableLValue (value(57005))
int main() {
return !printf("nonModifiableLValue=%x at %p\n",
nonModifiableLValue,
& nonModifiableLValue
);
}

:lolflag:


trent.josephsen

January 29th, 2011, 04:26 PM

In this discussion about C, I fail to see how test programs written in C++ are relevant. I really, really wish you wouldn't conflate the two with such obstinate regularity.


psusi

January 30th, 2011, 08:06 PM

Having an address does not make something an lvalue. Being able to use it on the left side of an assignment does.

A function also has an address, but is not an lvalue.


trent.josephsen

January 30th, 2011, 08:31 PM

What makes a function not an lvalue according to the Standard is that it does not have object type. The Standard does not define lvalue in terms of assignment statements.


psusi

January 30th, 2011, 08:44 PM

I'm pretty sure that is how the old one defined it. How does the new one?


trent.josephsen

January 30th, 2011, 09:55 PM

I'm pretty sure that is how the old one defined it. How does the new one?
As in my first post.

C99 is pretty easy to come by. I would be interested to see the text of C89 as it relates to lvalues, if somebody has access to it.

The reference manual in the back of my copy of K&R2 says

An object is a named region of storage; an lvalue is an expression referring to an object.
Of course, this isn't the language of C89 itself, but it falls in line with C99.

Google also found this page (http://www.lysator.liu.se/c/rat/c2.html), which has an interesting comment on 3.2.2.1 (although still without the wording of the Standard).


worksofcraft

January 30th, 2011, 11:44 PM

In this discussion about C, I fail to see how test programs written in C++ are relevant. I really, really wish you wouldn't conflate the two with such obstinate regularity.

Who said it's about C? IMO it is about the concept "lvalue". However specially for you I changed the include file name and the comment style so you can use the C compiler:


/* gcc modifiable.c */
#include <stdio.h>
enum { nonModifiableLValue = 57005 };
int main(int argc, char *argv[], char *envp[]) {
return !printf("nonModifiableLValue=%x at %p\n",
nonModifiableLValue,
& nonModifiableLValue
);
}


and lo... she still wants an lvalue:


$ gcc -Wall -pedantic modifiable.c
modifiable.c: In function ‘main’:
modifiable.c:8: error: lvalue required as unary ‘&’ operand


I was attempting to show an example of a non-modifiable lvalue and then to confirm that it was indeed considered an lvalue even though, being non modifiable it can't be used on the left hand side of an expression:


/* gcc modifiable.c */
#include <stdio.h>
const int nonModifiableLValue = 57005;
int main(int argc, char *argv[], char *envp[]) {
nonModifiableLValue = nonModifiableLValue;
}



$ gcc -Wall -pedantic modifiable.c
modifiable.c: In function ‘main’:
modifiable.c:5: error: assignment of read-only variable ‘nonModifiableLValue’

Perhaps you rather discuss the symantics of the actual wording of different versions of official standards, but I'm satisfied I have a clear mental picture of what constitutes an lvalue and what doesn't in any language.


Powered by vBulletin® Version 4.2.2 Copyright © 2018 vBulletin Solutions, Inc. All rights reserved.

Leave a Comment

(0 Comments)

Your email address will not be published. Required fields are marked *