Re: returning lvalue in C vs C++
- From: "Alf P. Steinbach" <alfps@xxxxxxxx>
- Date: Fri, 31 Mar 2006 10:42:35 +0200
* Ben C wrote, on 31.03.2006 09:55:
On 2006-03-30, Alf P. Steinbach <alfps@xxxxxxxx> wrote:* Ben C:f().x is _not_ an invalid lvalue, it's a perfectly good lvalue.I'm sorry, that's incorrect -- it's not an lvalue at all, it's an rvalue.
What's your definition of lvalue and rvalue?
I just looked in K&R, and it says, "An _object_ is a named region of
storage; an _lvalue_ is an expression referring to an object. An obvious
example of an lvalue is an identifier with suitable type and storage
class [...]"
Originally "l" and "r" denoted the left hand side and right hand side of an assignment operator.
I.e., an lvalue could occur on the left hand side of "=", and an rvalue only on the right hand side.
The C and C++ standards define lvalues and rvalues for each language (note that these terms refer to expressions, not to things in themselves).
In both languages a call of a function that produces a non-reference, is an rvalue (note: C does not have references).
In C++ you can call member functions on rvalues (note: C does not have member functions).
Not a precise definition, but I come away with the idea that lvalue is
storage, rvalue is what you store there.
An lvalue is an expression that, roughly, can occur on the left hand side of an assignment, as opposed to an rvalue, which is limited to right hand side. In C++ the picture is more complicated, because you can have 'const' lvalues, which you can't assign to. What you can do is take the address of a 'const' lvalue using the build-in address operator, if the built-in address operator is available; you cannot take the address of an rvalue using the built-in address operator, e.g., you cannot take the address of the number 666.
I'm suggesting that another example of an lvalue is a structure instance
returned from a function, on the basis that a structure instance is
always an object. f().x is an expression referring to a region of
storage, and so you can assign to it. Values of variables of structure
types are objects, values of variables of builtin types are not, they're
rvalues.
If you want to suggest that, then post to the appropriate language standard newsgroup, e.g. [comp.std.c++] for C++.
[snip]
So, in
f().x = 10;
f().x is the name of a storage region, but in y = f().x, it implicitly
means "what's stored there". The value of f() is a structure
instance, and therefore a region of storage.
Not necessarily. Small structs may be returned in registers. And although some computers, like the PDP-11 (IIRC), have had memory mapped registers, usually you can't form a machine code level address that identifies a register, and in C and C++ you can't, using the built-in address operator, take the address of something declared as 'register', or of any rvalue (which might reside in a register, or be just a part of a machine code instruction, for all you know).
The example below compiles and runs and prints out 20 using gcc -x c++,
but fails to compile with -x c.
To find what a language allows and not, as opposed to to a given implementation of that language, you need to consult the language standard -- or someone knowledgable about that sort of thing... ;-)
Here we're assigning t to f(), and then reading back the value of f().x
into y. I can't see anything wrong with it.
See above for (part of) the rationale; see the standard for the relevant language for the rules that consequently disallow the code.
#include <stdio.h>
struct thing
{
int x;
};
struct thing f(void)
{
struct thing ret = {10};
return ret;
}
int main(void)
{
struct thing t = {20};
int y = (f() = t).x;
This is invalid in both C and C++.
printf("%d\n", y);
return 0;
}
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
.
- Follow-Ups:
- Re: returning lvalue in C vs C++
- From: pete
- Re: returning lvalue in C vs C++
- From: Alan Johnson
- Re: returning lvalue in C vs C++
- References:
- returning lvalue in C vs C++
- From: Ben C
- Re: returning lvalue in C vs C++
- From: Phlip
- Re: returning lvalue in C vs C++
- From: Ben C
- Re: returning lvalue in C vs C++
- From: Ben C
- Re: returning lvalue in C vs C++
- From: Kai-Uwe Bux
- Re: returning lvalue in C vs C++
- From: Alf P. Steinbach
- Re: returning lvalue in C vs C++
- From: Ben C
- Re: returning lvalue in C vs C++
- From: Alf P. Steinbach
- Re: returning lvalue in C vs C++
- From: Ben C
- returning lvalue in C vs C++
- Prev by Date: Re: Subsequence problem
- Next by Date: Re: Card dealing and random repetition
- Previous by thread: Re: returning lvalue in C vs C++
- Next by thread: Re: returning lvalue in C vs C++
- Index(es):
Relevant Pages
|