Topic: this a const pointer?
Author: jkanze@otelo.ibmmail.com
Date: 1998/05/12 Raw View
[Cross-posted to comp.std.c++, because this has really become
purely a standards questions, and is only of interest to
language lawyers. I'd set followups there if I could, but
I'm posting through DejaNews, which doesn't allow it. Maybe
the moderators will be kind enough to do it for me.]
[ done. -sdc ]
In article <6j6m2l$864@netlab.cs.rpi.edu>,
jpotter@falcon.lhup.edu (John Potter) wrote:
>
> "Daniel Parker" <danielp@nospam.com> wrote:
>
> : Cristian Georgescu wrote in message <6j1u8u$m0t@netlab.cs.rpi.edu>...
> : >Is "this" a const pointer?
> : >
>
> : class A
> : {
> : public:
> : void f();
> : void f() const;
> : };
>
> : void A::f()
> : {
> : // this pointer is non-const
>
> s/pointer is/is pointer to/
>
> : }
>
> : void A::f() const
> : {
> : // this pointer is const
>
> s/pointer is/is pointer to/
>
> : }
>
> A very nice answer, but I don't think it matches the question.
>
> I read the question as asking if in your examples the type of this is
> A* const and A const* const respectively.
>
> The answer is _no_ :
>
> | 9.3.2[class.this]/1
> | In the body of a nonstatic (_class.mfct_) member function, the
> | keyword this is a non-lvalue expression whose value is the
> | address of the object for which the function is called.
>
> However, it does act much like a const pointer, maybe.
It's more than const; it's not even an lvalue. Note that the expression
"3" has type "int", and not type "int const".
> #include <iostream.h>
> struct C {
> void f () { ++ this; }
Constraint violation: the operand to ++ must be an lvalue.
> void g () { ++ (C*&)this; }
Interesting question. The answer should be the same as "++ (int&)3".
IMHO, the cast should be illegal, but the standard says otherwise.
Consider the following:
++ const_cast< int& >( static_cast< int const& >( 3 ) ) ;
According to 5.2.9, static_cast< T >( e ) is legal if the declaration
T t(e) is well formed, and "int const& t( 3 )" is well formed, so
the static_cast is legal. The const_cast just casts away const, so
it is legal. The result of the const_cast is a reference, and so
an lvalue, so the ++ operator is legal. I'm not sure what the
semantics are supposted to be, though. I suspect that it involves
creating a temporary, initializing it to 3, and then incrementing
it. And that the results had better be 4 every time the expression
is executed -- the temporary must be destructed at the end of the
full expression, and reconstructed each time.
Now consider "++ (int&)3", using a cast-expression. In 5.4, it says
that the conversion performed by a static_cast followed by a const_cast
can be performed using the cast notation; since we've just shown that
this conversion can be performed by a static_cast followed by a const_cast,
the use of the cast notation is legal.
Now replace "3" with "this", and "int" with "T*", and we're back to the
original problem.
There is one point I'm not sure of: attempting to modify a const object
is undefined behavior. But what about attempting to modify an rvalue?
I suspect that this is something so fundamental that the standard
"forgets" to say anything about it. (Rvalues of non-class type are
not objects, so how can you modify something that isn't. On the other
hand, is it undefined behavior, or...)
One last remark: if an rvalue is *bound* to a const reference (in
initialization), the situation is slightly different, in that the
standard explicitly says that a temporary OBJECT will be created.
That temporary object has the type of the reference, however, thus
const int, and so any attempt to modify it results in undefined
behavior. Perhaps it is the intent that casting to a reference
type effectively creates a temporary reference type initialized
with the expression being cast. (IMHO, this would seem the most
reasonable interpretation.)
> void h (C* const This) { ++ (C*&)This; }
> };
>
> My older compilers reject f, accept g and modify this. G++ 2.8.0
> gives a warning on g and the ++ does not change the value of this.
> Since this is a non-lvalue, the cast is invalid. If it were a
> non-modifiable lvalue as in h, then it would be valid. So _This_ is a
> const pointer but _this_ is not.
In this case, it is clear. "This" is a const object, so any attempt to
modify it is undefined behavior. Which means that anything the compiler
does is correct. (I think that it is required to compile the program,
however, although a warning would not be illegal.)
--
James Kanze +33 (0)1 39 23 84 71 mailto: kanze@gabi-soft.fr
+49 (0)69 66 45 33 10 mailto: jkanze@otelo.ibmmail.com
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
Conseils en informatique orient e objet --
-- Beratung in objektorientierter Datenverarbeitung
-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/ Now offering spam-free web-based newsreading
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]