 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Matthias Hofmann Guest
|
Posted: Sun Sep 14, 2003 12:02 am Post subject: Is *this an lvalue? |
|
|
Hello!
I have just consulted the standard about the typeid operator and I stumbled
into something that strikes me as funny. It's included in the following
passage:
5.2.8 Type identification
(2) When typeid is applied to an lvalue expression whose type is a
polymorphic class type (10.3), the result refers to a type_info object
representing the type of the most derived object [...] to which the lvalue
refers.
(3) When typeid is applied to an expression other than an lvalue of a
polymorphic class type, the result refers to a type_info object representing
the static type of the expression.
So when I apply the typeid operator to an rvalue, I get the static type.
This is interesting because I have just learned to use the template pattern
to implement virtual constructors in the following way:
class MyClass
{
public:
MyClass* Clone()
{
MyClass* p = DoClone();
ASSERT( typeid( *this ) == typeid( *p );
return p;
}
private:
virtual MyClass* DoClone() = 0;
};
The ASSERT uses the typeid operator to ensure that DoClone() is redefined in
the most derived class. In order for this to work, typeid must return the
dynamic type of both *this and *p. However, I found the following about the
this pointer in the standard:
9.3.2 The this pointer
(1) In the body of a nonstatic member function, the keyword this is a
non-lvalue expression whose value is the address of the object for which the
function is called.
If the this pointer is an non-lvalue, I wonder wether *this is an lvalue -
as otherwise the ASSERT will not work properly. Is this true? Do I always
get an lvalue if I dereference a pointer?
Best regards,
Matthias Hofmann
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
John Potter Guest
|
Posted: Sun Sep 14, 2003 1:39 am Post subject: Re: Is *this an lvalue? |
|
|
On 13 Sep 2003 20:02:00 -0400, "Matthias Hofmann"
<hofmann (AT) anvil-soft (DOT) com> wrote:
| Quote: | 9.3.2 The this pointer
(1) In the body of a nonstatic member function, the keyword this is a
non-lvalue expression whose value is the address of the object for which the
function is called.
|
Since this is a non-lvalue, assignment is not allowed and its address
may not be taken.
| Quote: | If the this pointer is an non-lvalue, I wonder wether *this is an lvalue -
as otherwise the ASSERT will not work properly. Is this true? Do I always
get an lvalue if I dereference a pointer?
|
Yes. 5.3.1/1.
John
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Gabriel Dos Reis Guest
|
Posted: Sun Sep 14, 2003 11:24 am Post subject: Re: Is *this an lvalue? |
|
|
"Matthias Hofmann" <hofmann (AT) anvil-soft (DOT) com> writes:
| Quote: | If the this pointer is an non-lvalue, I wonder wether *this is an lvalue -
|
yes, it is. See paragraph on unary *.
| Quote: | Do I always
get an lvalue if I dereference a pointer?
|
yes.
--
Gabriel Dos Reis <gdr (AT) integrable-solutions (DOT) net>
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Daniel Pfeffer Guest
|
Posted: Tue Sep 16, 2003 12:00 pm Post subject: Re: Is *this an lvalue? |
|
|
"Matthias Hofmann" <hofmann (AT) anvil-soft (DOT) com> wrote
<snip>
| Quote: | 9.3.2 The this pointer
(1) In the body of a nonstatic member function, the keyword this is a
non-lvalue expression whose value is the address of the object for which
the
function is called.
If the this pointer is an non-lvalue, I wonder wether *this is an lvalue -
as otherwise the ASSERT will not work properly. Is this true? Do I always
get an lvalue if I dereference a pointer?
|
It depends whether you are in a const method or not. For example:
class X {
public:
// implementation details omitted
void foo(const X &x) // X * const this; ('this' is a constant pointer
to a variable 'X')
{
*this = x; // calls X::operator =(const X &);
}
void foo(const X &x) const // const X * const this; ('this' is a
constant pointer to a const 'X')
{
*this = x; // error!
}
};
By extension, dereferencing a pointer to a variable object will give you an
lvalue. Dereferencing a pointer to a const object will give you a
non-lvalue.
HTH
Daniel Pfeffer
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Attila Feher Guest
|
Posted: Tue Sep 16, 2003 8:32 pm Post subject: Re: Is *this an lvalue? |
|
|
Daniel Pfeffer wrote:
[SNIP]
| Quote: | By extension, dereferencing a pointer to a variable object will give
you an lvalue. Dereferencing a pointer to a const object will give
you a non-lvalue.
|
Is it so? So far I thought it is an lvalue (object has memory - at least by
the C definition) only a const one. Where is it in the standard where it
says that it is not an lvalue? What does "non-lvalue" mean here? Isn't
that rvalue? Or there is something in between? If yes: what is that
called?
--
Attila aka WW
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Gabriel Dos Reis Guest
|
Posted: Tue Sep 16, 2003 8:36 pm Post subject: Re: Is *this an lvalue? |
|
|
"Daniel Pfeffer" <pfefferd (AT) hotmail (DOT) co.il> writes:
| Quote: | If the this pointer is an non-lvalue, I wonder wether *this is an lvalue -
as otherwise the ASSERT will not work properly. Is this true? Do I always
get an lvalue if I dereference a pointer?
It depends whether you are in a const method or not.
|
No.
"lvalue" does not mean "modifiable". There can be non-modifiable
lvalues and there can be modifiable rvalues.
| Quote: | By extension, dereferencing a pointer to a variable object will give you an
lvalue. Dereferencing a pointer to a const object will give you a
non-lvalue.
|
Wrong.
Dereferencing a pointer to "const T" gives an lvalue, albeit non-modifiable.
--
Gabriel Dos Reis <gdr (AT) integrable-solutions (DOT) net>
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Falk Tannhäuser Guest
|
Posted: Tue Sep 16, 2003 8:52 pm Post subject: Re: Is *this an lvalue? |
|
|
Daniel Pfeffer wrote:
| Quote: | [...] dereferencing a pointer to a variable object will give
you an lvalue.
Yes (a non-const one).
Dereferencing a pointer to a const object will give you a
non-lvalue.
No - it gives a 'const' lvalue. Unlike a non-const lvalue, |
it can't be assigned to or otherwise modified (except using
const_cast or mutable members ...) but it still has an address
and an identity.
Falk
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
John Potter Guest
|
Posted: Wed Sep 17, 2003 9:45 am Post subject: Re: Is *this an lvalue? |
|
|
On 16 Sep 2003 08:00:01 -0400, "Daniel Pfeffer" <pfefferd (AT) hotmail (DOT) co.il>
wrote:
| Quote: | "Matthias Hofmann" <hofmann (AT) anvil-soft (DOT) com> wrote in message
news:bjvta6$7ir$1 (AT) news1 (DOT) nefonline.de...
If the this pointer is an non-lvalue, I wonder wether *this is an lvalue -
as otherwise the ASSERT will not work properly. Is this true? Do I always
get an lvalue if I dereference a pointer?
It depends whether you are in a const method or not. For example:
class X {
public:
// implementation details omitted
void foo(const X &x) // X * const this; ('this' is a constant pointer
to a variable 'X')
|
No, this is an rvalue, not a pointer, with type X*. Pointers are
fundamental types where rvalues are never const.
&this; // invalid
X* const& that(this); // creates and binds to a temporary
| Quote: | {
*this = x; // calls X::operator =(const X &);
}
|
Yes, *this is an lvalue of type X&.
&*this; // valid
| Quote: | void foo(const X &x) const // const X * const this; ('this' is a
constant pointer to a const 'X')
|
An rvalue of type X const* as above.
| Quote: | {
*this = x; // error!
|
Yes, *this is an lvalue of type X const&.
&*this; // valid
| Quote: | }
};
By extension, dereferencing a pointer to a variable object will give you an
lvalue.
|
Yes.
| Quote: | Dereferencing a pointer to a const object will give you a
non-lvalue.
|
No. It gives an lvalue. A reference to const. Lvalue/rvalue and
const/non-const are orthogonal.
int i;
int const& r(i); // An lvalue not usable on left of =
X x;
X() = x; // An rvalue used on the left of =
John
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Ron Natalie Guest
|
Posted: Wed Sep 17, 2003 9:46 am Post subject: Re: Is *this an lvalue? |
|
|
"Attila Feher" <attila.feher (AT) lmf (DOT) ericsson.se> wrote
| Quote: | Daniel Pfeffer wrote:
[SNIP]
By extension, dereferencing a pointer to a variable object will give
you an lvalue. Dereferencing a pointer to a const object will give
you a non-lvalue.
Is it so? So far I thought it is an lvalue (object has memory - at least by
the C definition) only a const one. Where is it in the standard where it
says that it is not an lvalue? What does "non-lvalue" mean here? Isn't
that rvalue? Or there is something in between? If yes: what is that
called?
|
It is an lvalue. 5.3.1 clearly says so (doesn't mention const anywhere).
Despite the unfortunate name, not all lvalues are legal left hand side of
assignment expressions.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
thp@cs.ucr.edu Guest
|
Posted: Thu Sep 18, 2003 10:08 am Post subject: Re: Is *this an lvalue? |
|
|
Attila Feher <attila.feher (AT) lmf (DOT) ericsson.se> wrote:
+ Daniel Pfeffer wrote:
+ [SNIP]
+> By extension, dereferencing a pointer to a variable object will give
+> you an lvalue. Dereferencing a pointer to a const object will give
+> you a non-lvalue.
+
+ Is it so? So far I thought it is an lvalue (object has memory - at least by
+ the C definition) only a const one. Where is it in the standard where it
+ says that it is not an lvalue? What does "non-lvalue" mean here?
IIRC, the C++ standard never actually defines "lvalue", and the C
standard has blown two attempts at defining "lvalue":
- C90 defined "lvalue" as "any expression that denotes an object",
which eliminates "*p" when p is 0 -- an absurdity, since compilers
must statically determine semantic correctness.
- C99 attempted to correct this problem with the definition that an
lvalue is "any expression of an object type", which makes "3" an
lvalue -- another absurdity.
Tom Payne
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Gabriel Dos Reis Guest
|
Posted: Fri Sep 19, 2003 10:13 am Post subject: Re: Is *this an lvalue? |
|
|
[email]thp (AT) cs (DOT) ucr.edu[/email] writes:
| Quote: | IIRC, the C++ standard never actually defines "lvalue",
|
C++ standard defines lvalue by extension (as opposed to comprehension).
--
Gabriel Dos Reis <gdr (AT) integrable-solutions (DOT) net>
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Attila Feher Guest
|
Posted: Fri Sep 19, 2003 10:15 am Post subject: Re: Is *this an lvalue? |
|
|
[email]thp (AT) cs (DOT) ucr.edu[/email] wrote:
| Quote: | IIRC, the C++ standard never actually defines "lvalue", and the C
standard has blown two attempts at defining "lvalue":
- C90 defined "lvalue" as "any expression that denotes an object",
which eliminates "*p" when p is 0 -- an absurdity, since
compilers must statically determine semantic correctness.
- C99 attempted to correct this problem with the definition that an
lvalue is "any expression of an object type", which makes "3" an
lvalue -- another absurdity.
|
I guess you might have a different meaning for object than what the C
standard means there. C99 3.14 object "region of data storage in the
execution environment, the contents of which can represent values".
According to this *p if p is zero does not denote an object. Neither does
3, since it is a literal, which does not necessarily have an associated data
storage. At least AFAIK.
--
Attila aka WW
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Ron Natalie Guest
|
Posted: Fri Sep 19, 2003 11:10 am Post subject: Re: Is *this an lvalue? |
|
|
<thp (AT) cs (DOT) ucr.edu> wrote
| Quote: | IIRC, the C++ standard never actually defines "lvalue", and the C
standard has blown two attempts at defining "lvalue":
|
C++ defines it (weakly) in 3.10.
What is amusing is that C++ defines rvalue (as things that are not lvalues).
C doesn't even use that term.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Gabriel Dos Reis Guest
|
Posted: Fri Sep 19, 2003 11:22 am Post subject: Re: Is *this an lvalue? |
|
|
"Attila Feher" <attila.feher (AT) lmf (DOT) ericsson.se> writes:
| Quote: | thp (AT) cs (DOT) ucr.edu wrote:
IIRC, the C++ standard never actually defines "lvalue", and the C
standard has blown two attempts at defining "lvalue":
- C90 defined "lvalue" as "any expression that denotes an object",
which eliminates "*p" when p is 0 -- an absurdity, since
compilers must statically determine semantic correctness.
- C99 attempted to correct this problem with the definition that an
lvalue is "any expression of an object type", which makes "3" an
lvalue -- another absurdity.
I guess you might have a different meaning for object than what the C
standard means there. C99 3.14 object "region of data storage in the
execution environment, the contents of which can represent values".
|
I think you missed Tom's point: "3" is an expression, which has type
"int", an object type.
| Quote: | According to this *p if p is zero does not denote an object. Neither does
3, since it is a literal, which does not necessarily have an associated data
storage. At least AFAIK.
|
lvaluness/rvalueness is a static notion, i.e. a notion derived from
static analysis of a program text. Determining whether p is null, most
of the time, is a dynamic notion, i.e. requires a dynamic analysis.
Therefore, *p as an expression is an lvalue from a static analysis
point of view, but is meaningless from a dynamic analysis point of view.
--
Gabriel Dos Reis <gdr (AT) integrable-solutions (DOT) net>
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
thp@cs.ucr.edu Guest
|
Posted: Sat Sep 20, 2003 10:48 pm Post subject: Re: Is *this an lvalue? |
|
|
Gabriel Dos Reis <gdr (AT) integrable-solutions (DOT) net> wrote:
+ [email]thp (AT) cs (DOT) ucr.edu[/email] writes:
+
+ | IIRC, the C++ standard never actually defines "lvalue",
+
+ C++ standard defines lvalue by extension (as opposed to comprehension).
IMHO, it would have been simpler and clearer to define lvalue
syntactically.
Tom Payne
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|