|
Boost : |
From: Schoenborn, Oliver (Oliver.Schoenborn_at_[hidden])
Date: 2002-10-07 11:44:17
> From: Daniel Frey [mailto:daniel.frey_at_[hidden]]
>
> "Schoenborn, Oliver" wrote:
> >
> > I took a look at the C++ Standard. Paragraph 10 of section 5.2.10 is
> > interesting:
> >
> > "An lvalue expression of type T1 can be cast to the type
> "reference to T2"
> > if an expression of type "pointer to T1" can be explicitly
> converted to the
> > type "pointer to T2" using a reinterpret_cast. ... The
> result is an lvalue
> > that refers to the same object as the source lvalue, but
> with a different
> > type. No temporary is created, no copy is made, and
> constructors (12.1) or
> > conversion functions (12.3) are not called."
>
> The last sentence is the important one.
>
> > So the reinterpret_cast solution is standard only if there
> is something in
> > the Standard that says that the layout for a class<T> MUST
> be the same as
> > that for class<const T>, which I don't think is the case
> (though in practice
> > it probably ends up like that). Paragraph 10 suggests to me that a
>
> My pointer-class contains only a single data element, which is a real
> pointer to T, hence a 'T*' or a 'const T*'. I cannot imagine any sane
> compiler to create different layouts in this case.
After the reinterpret cast, the compiler uses a given area of memory as
though it were a ptr<const T> rather than a ptr<T>. I believe this is not
just data, it's the associated methods too. Let's say you call ptr<const
T>::method() on the reinterpreted object. And say the ptr<const T> has not
been used in another part of your translation unit. Does the compiler
instantiate ptr<const T>::method(), or does the reinterpret cast also tell
it that this method already exists (because it was instantiated for ptr<T>)?
The latter seems unlikely if the compiler keeps some sort of name table, and
seems likely only if compiler actually looks at what object code it has
produced in memory.
>
> > reinterpret cast of the type discussed is not safe when the
> two classes are
> > separate, ie is only safe when the cast is within an
> inheritance branch,
> > because you can't be sure that the same methods are
> instantiated in both.
>
> It's not the methods, it's the object that they expect. As described in
> my other post, it may be a problem if you have a vtbl, otherwise, you
> can call a method which has been instantiated for a 'const T*' on a
> reinterpretated 'T*' and the other way is not possible as there is no
> cast from ptr< const T > to ptr< T >.
There's a big different between reinterpreting a T* to a const T*, and
reinterpreting a class<T*> to a class<const T*>, so I don't understand what
you mean there.
Oliver
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk