yesterday I could do this to:
If by yesterday, you mean roughly 20 years ago, yes. This was
banned somewhere around the time CFront 2.0 was released, I
think (before I started using C++, at any rate), because
experience showed it to be far too error prone.
The circumstances have changed significantly since then. If it
were a question of banning it today, it wouldn't stand a chance
of passing, because it would break existing code. Back in the
late 1980's, however, there was a lot less existing C++ code,
and it was more or less understood that the language was still
evolving---there wasn't an ISO standard, or even a committee to
create one.
so,today we are much more limited.
Yeh. There's a large category of errors we cannot make
.
(Seriously, there are times when the rule is limiting, as well
as times when it saves you. But it's certainly not a new rule,
and it's hard to imagine anyone today having to deal with code
which was written before it existed.)
I meant intrinsic addressing, not using a member to extract the
address from inside scope to global.
I was addressing the more fundamental issue. For built-in
types, and lvalue *must* have an address; an rvalue typically
doesn't. (It will be in a register, or embedded in an
instruction.) For class types, at least class types with member
functions, even an rvalue must have an address (at least until
the "as if" rule kicks in). The distinction between lvalue and
rvalue is much more tenuous, or at least, harder to associate
with some more fundamental characteristic.
[...]
I know. But I assume it to be an auto defined member.
You assume wrong. It's a keyword, which designates an
expression. In many ways, it's more like a literal, e.g. 42, or
3.14159, except that it's value depends on context.
That's according to the standard, of course. As I said when I
brought the point up, it's really a nit. If you want to think
of it as a predefined, preinitialized local variable (not a
member), I don't think that that's a big problem, as long as you
consider it const. The effect would probably be about the same.
But that's not the way the standard defines it.
general speaking 'const' objects can not appear to the left side of
assignment(except for some odd classes that do define it on const
objects).should we consider every const an rvalue then?
I said "historically". As far as I know, the term lvalue was
first used by Kernighan and Richie, and that's the justification
they gave for its name. At the time, of course, there was no
const. But the & operator also required an lvalue. That's why
I put the comment in parentheses, and added:
rvalues used to be either literals or function return values
in C.
Not only. Something like "&a
" or "(double)i" is also an
rvalue, even though there is no literal nor any function in the
expression.
But you mean that since the declaration of C++ 'this'
has formed a single-membered categury of rvalues.
No. Even in C, each expression is defined as resulting in
either an lvalue or not an lvalue (an rvalue). There are no
"categories". In both standards, unless an expression is
explicitely stated to result in an lvalue, it results in an
rvalue. Thus, in the C standard, we have "An identifier is a
primary expression, provided it has been declared as designating
an object (in which case it is an lvalue) or a function (in
which case it is a function designator)." And nothing in §6.5.4
(Cast Operators) which says that the results are an lvalue, so
they are an rvalue.
And in the C++ standard, we have "The keyword this [...]. The
expression is an rvalue." In the section concerning primary
expressions; there is no legal use of "this" outside of an
expression.
That looks odd to me ,I can fancy 'this' as a pointer-return
member function that results in an rvalue but that is not
consistent with function call syntax in C++.
Finally, I should ask if there is any practical distinction
between R & L in C++ today?
Practically: for built-in types, yes. For class types, it
mainly affects whether you can bind to a non-const reference or
not. Formally: it plays a role anytime built-in operators are
used (but that's rarely the case for class types, since most
built-in operators don't apply to them).