ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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?
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:
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).
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
= *= /= %= += -= >>= <<= &= ˆ= |=
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?
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.
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
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 ...
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.
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.
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
}
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?
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.