LinuxQuestions.org
Review your favorite Linux distribution.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 12-21-2011, 03:47 AM   #1
Aquarius_Girl
Senior Member
 
Registered: Dec 2008
Posts: 4,731
Blog Entries: 29

Rep: Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940
C++: What EXACTLY comprises a LValue?


From C++ standard:
3.10
Quote:
An lvalue (so called, historically, because lvalues could appear on the left-hand side of an assignment expression) designates a function or an object. [ Example: If E is an expression of pointer type, then *E is an lvalue expression referring to the object or function to which E points. As another example, the result of calling a function whose return type is an lvalue reference is an lvalue.
5.17
Quote:
The assignment operator (=) and the compound assignment operators all group right-to-left. All require a modifiable lvalue as their left operand
So, is LValue some "user modifiable" piece of memory?

Is
Code:
const int x = 0;
'x' a LValue since it is modifiable?
 
Old 12-21-2011, 04:17 AM   #2
Doc CPU
Senior Member
 
Registered: Jun 2011
Location: Stuttgart, Germany
Distribution: Mint, Debian, Gentoo, Win 2k/XP
Posts: 1,099

Rep: Reputation: 344Reputation: 344Reputation: 344Reputation: 344
Quote:
Originally Posted by Anisha Kaul View Post
Is
Code:
const int x = 0;
'x' a LValue since it is modifiable?
no, not exactly. Of course, 'x' is an LValue, but the explanation isn't quite correct.

A so-called LValue is an expression that refers to a memory location. Most commonly, that would be a variable. But it could also be a dereferenced expression that results in a pointer, or a function that returns a pointer. Let's look at this nonsense code:

Code:
BYTE *foo(int address)
 { return (BYTE *) address;
 }
Then *foo(42) would be an LValue, as well as *((WORD *)(index*18+4)) is an LValue. Both expressions evaluate to a pointer which is then dereferenced, and that refers to a memory location, just like the name of a variable (or object or function).

The historical definition you quoted explains that pretty well, I think: An LValue is anything that may appear on the left side of the assignment operator (the = sign).

[X] Doc CPU
 
1 members found this post helpful.
Old 12-21-2011, 04:21 AM   #3
Aquarius_Girl
Senior Member
 
Registered: Dec 2008
Posts: 4,731

Original Poster
Blog Entries: 29

Rep: Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940
So, do you mean that anything by which we can modify the memory region, is a LValue?
 
Old 12-21-2011, 04:38 AM   #4
Doc CPU
Senior Member
 
Registered: Jun 2011
Location: Stuttgart, Germany
Distribution: Mint, Debian, Gentoo, Win 2k/XP
Posts: 1,099

Rep: Reputation: 344Reputation: 344Reputation: 344Reputation: 344
Hi there,

Quote:
Originally Posted by Anisha Kaul View Post
So, do you mean that anything by which we can modify the memory region, is a LValue?
basically, yes: The possibility of an expression to modify memory contents.
Is it that simple? Hmm, looks like. :-)

[X] Doc CPU
 
Old 12-21-2011, 05:00 AM   #5
SigTerm
Member
 
Registered: Dec 2009
Distribution: Slackware 12.2
Posts: 379

Rep: Reputation: 234Reputation: 234Reputation: 234
Quote:
Originally Posted by Anisha Kaul View Post
Is
Code:
const int x = 0;
'x' a LValue since it is modifiable?
I might be mistaken about this one, but I do not think is an assignment.
As far as I know, this is "initializer". See 8.5 (dcl.init) of ISO/IEC 14882:2003(E).

Compare:
Code:
int a[] = {1, 2, 3, 4, 5};
Not an assignment.

"Assignment" is explained in 5.17 (expr.ass) and includes several operators.
Code:
assignment-operator: one of
    = *= /= %= += -= >>= <<= &= ˆ= |=
 
Old 12-21-2011, 05:19 AM   #6
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,862
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
As far as I know lvalue is a syntactical category, so const doesn't matter...
 
Old 12-21-2011, 05:19 AM   #7
Aquarius_Girl
Senior Member
 
Registered: Dec 2008
Posts: 4,731

Original Poster
Blog Entries: 29

Rep: Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940
Q: Integer literals are also not maniputable, therefore they are NOT considered LValues?
Q: Temporary objects created by the compiler on the stack are also NOT considered LValues since _WE_ can't modify them?
 
Old 12-21-2011, 05:20 AM   #8
Doc CPU
Senior Member
 
Registered: Jun 2011
Location: Stuttgart, Germany
Distribution: Mint, Debian, Gentoo, Win 2k/XP
Posts: 1,099

Rep: Reputation: 344Reputation: 344Reputation: 344Reputation: 344
Hi there,

Quote:
Originally Posted by SigTerm View Post
Code:
const int x = 0;
I might be mistaken about this one, but I do not think is an assignment.
As far as I know, this is "initializer". See 8.5 (dcl.init) of ISO/IEC 14882:2003(E).
perfectly true - but to use an initializer, you also need an LValue, because you can only initialize something that maps to a memory location.
So your veto is correct, but not relevant in this particular matter.

[X] Doc CPU
 
1 members found this post helpful.
Old 12-21-2011, 05:23 AM   #9
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,862
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
Literals (number, character, string etc) aren't lvalues.
Compiler internal objects aren't lvalues.
 
Old 12-21-2011, 05:24 AM   #10
Aquarius_Girl
Senior Member
 
Registered: Dec 2008
Posts: 4,731

Original Poster
Blog Entries: 29

Rep: Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940
I know they aren't. In post 7 I was confirming the reasons.
 
Old 12-21-2011, 05:30 AM   #11
Doc CPU
Senior Member
 
Registered: Jun 2011
Location: Stuttgart, Germany
Distribution: Mint, Debian, Gentoo, Win 2k/XP
Posts: 1,099

Rep: Reputation: 344Reputation: 344Reputation: 344Reputation: 344
Hi there,

Quote:
Originally Posted by Anisha Kaul View Post
Q: Integer literals are also not maniputable, therefore they are NOT considered LValues?
Correct. If they were, a statement like
Code:
42 = 40+2;
would compile without an error. But it doesn't, because 42 is not an LValue and consequently doesn't satisfy the requirement of the = operator.

Quote:
Originally Posted by Anisha Kaul View Post
Q: Temporary objects created by the compiler on the stack are also NOT considered LValues since _WE_ can't modify them?
Not correct. Technically, a temporary object can be an LValue, but I can't think of a situation to make use of that. The following bogus sample is the closest I can get at the moment:
Code:
char **arr;
(arr[x]=argv[1])[0] = '\0';
However, arr[x] is not really a temporary object ...

[X] Doc CPU
 
Old 12-21-2011, 05:33 AM   #12
Aquarius_Girl
Senior Member
 
Registered: Dec 2008
Posts: 4,731

Original Poster
Blog Entries: 29

Rep: Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940
Quote:
Originally Posted by Doc CPU View Post
Not correct. Technically, a temporary object can be an LValue,
3.10
Quote:
An rvalue (so called, historically, because rvalues could appear on the right-hand side of an assignment
expression) is an xvalue, a temporary object (12.2) or subobject thereof, or a value that is not associated
with an object.
 
Old 12-21-2011, 06:38 PM   #13
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
I consider (and do not claim this to be official/strict) that the essence of 'lvalue' is 'left value' and that that 'value' can be a result of expression evaluation.

For example, one can write:

Code:
a[10] = 2;
or one can write the same as

Code:
*(a + 10) = 2;
- in the latter case the '(a + 10)' expression is the one that returns the lvalue.

This all is in addition to what's already been said.
 
Old 12-21-2011, 06:50 PM   #14
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
LValue exists not only in C/C++. For example, in Perl 'substr' function can be called as lvalue - from ('perldoc -f substr') :

Code:
       substr EXPR,OFFSET,LENGTH,REPLACEMENT
       substr EXPR,OFFSET,LENGTH
       substr EXPR,OFFSET
               Extracts a substring out of EXPR and returns it.  First character is at offset 0, or whatever you've set $[ to (but don't do that).  If OFFSET
               is negative (or more precisely, less than $[), starts that far from the end of the string.  If LENGTH is omitted, returns everything to the end
               of the string.  If LENGTH is negative, leaves that many characters off the end of the string.

                   my $s = "The black cat climbed the green tree";
                   my $color  = substr $s, 4, 5;       # black
                   my $middle = substr $s, 4, -11;     # black cat climbed the
                   my $end    = substr $s, 14;         # climbed the green tree
                   my $tail   = substr $s, -4;         # tree
                   my $z      = substr $s, -4, 2;      # tr

               You can use the substr() function as an lvalue, in which case EXPR must itself be an lvalue.  If you assign something shorter than LENGTH, the
               string will shrink, and if you assign something longer than LENGTH, the string will grow to accommodate it.  To keep the string the same length
               you may need to pad or chop your value using "sprintf".

               If OFFSET and LENGTH specify a substring that is partly outside the string, only the part within the string is returned.  If the substring is
               beyond either end of the string, substr() returns the undefined value and produces a warning.  When used as an lvalue, specifying a substring
               that is entirely outside the string is a fatal error.  Here's an example showing the behavior for boundary cases:

                   my $name = 'fred';
                   substr($name, 4) = 'dy';            # $name is now 'freddy'
                   my $null = substr $name, 6, 2;      # returns '' (no warning)
                   my $oops = substr $name, 7;         # returns undef, with warning
                   substr($name, 7) = 'gap';           # fatal error

               An alternative to using substr() as an lvalue is to specify the replacement string as the 4th argument.  This allows you to replace parts of the
               EXPR and return what was there before in one operation, just as you can with splice().

                   my $s = "The black cat climbed the green tree";
                   my $z = substr $s, 14, 7, "jumped from";    # climbed
                   # $s is now "The black cat jumped from the green tree"

               Note that the lvalue returned by the 3-arg version of substr() acts as a 'magic bullet'; each time it is assigned to, it remembers which part of
               the original string is being modified; for example:

                   $x = '1234';
                   for (substr($x,1,2)) {
                       $_ = 'a';   print $x,"\n";      # prints 1a4
                       $_ = 'xyz'; print $x,"\n";      # prints 1xyz4
                       $x = '56789';
                       $_ = 'pq';  print $x,"\n";      # prints 5pq9
                   }
 
Old 12-21-2011, 09:31 PM   #15
Aquarius_Girl
Senior Member
 
Registered: Dec 2008
Posts: 4,731

Original Poster
Blog Entries: 29

Rep: Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940Reputation: 940
Quote:
Originally Posted by Anisha Kaul View Post
Q: Temporary objects created by the compiler on the stack are also NOT considered LValues since _WE_ can't modify them?
3.10
Quote:
An rvalue (so called, historically, because rvalues could appear on the right-hand side of an assignment
expression) is an xvalue, a temporary object (12.2) or subobject thereof, or a value that is not associated
with an object.
Temporary objects ARE RValues, but is the reason that WE can't modify them, or something else?
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
invalid lvalue in assignment cdw9997 Programming 9 05-05-2009 06:16 PM
lvalue operator / consumable objects ta0kira Programming 8 10-23-2008 09:27 PM
error: invalid lvalue in assignment nasim751 Programming 3 04-10-2008 01:59 PM
Error: invalid lvalue in assignment xxrsc Linux - Software 1 08-17-2006 01:43 PM
wait_event_interruptible - invalid lvalue in unary `&' 7.e.Q Programming 4 11-08-2004 02:00 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 02:50 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration