Boost logo

Boost :

From: Simonson, Lucanus J (lucanus.j.simonson_at_[hidden])
Date: 2007-10-10 16:38:59


Steven wrote:
>Even without overriding virtuals, technically such a cast is wrong.
>"If a nonstatic member function of a class X is called for an object
>that is not of type X, or of a type derived from X, the behavior is
>undefined." (9.3.1/1)

Ah, I see, because I am calling functions of the derived type on an
object of the base type you believe that the behavior is undefined.
This would be true if the derived type added data members or virtual
pointer. In fact, I really struggled with the compiler's stubborn
refusal to treat the derived type and the base type as equivalent when
designing and implementing the design pattern. It really made me wish
for features in that language that don't exist...yet.

If I used composition, I would call a function of my composed type on an
object of type X (by reinterpret_cast) and it also appears that the
standard states that the behavior is undefined based upon your citation.
This doesn't convince me that it isn't safe, just that it might not be
safe, which we already knew.

>reinterpret_cast at least guarantees reversibility, static_cast
>doesn't even do that.
>static_cast:
>"If the rvalue of type "pointer to cv1 B" points to a B that is
>actually a sub-object of an object of type D, the resulting
>pointer points to the enclosing object of type D. Otherwise,
>the result of the cast is undefined." (5.2.9/8)

Yes, if the derived class adds virtual function pointer not present in
the base class, or uses multiple inheritance its pointer value may
differ from the address of the base class data enclosed within it. I
think it is safe to say that we understand this fact and can design
around it. Do you know of any other way the pointer values may be
different?

>My main issue is that you are relying on unspecified and/or undefined
>behavior to accomplish this. One possible solution is to store a
pointer
>rather than a copy. This is problematic when you need a temporary
though,
>because you would need two types--one that stores a pointer and one
that
>can hold a value.

I don't for a minute believe that the behavior I am relying upon is
unspecified or undefined. It is specified in the compiler, and all the
compilers somehow managed to agree on the definition and specify it the
same way. I would be quite surprised if it wasn't the standard that led
to this remarkable standardization of C++ compiler front-ends. Perhaps
the burden of proof falls upon me, but I don't think I should be
considered wrong until proven right. The code works and is perfectly
portable. I must have known something when I was designing it. Yes,
almost any other solution for doing what I'm trying to do is
problematic. It was very problematic to coax the compiler and language
to do what I wanted them to. Translating the idea into legal syntax was
quite challenging.

Luke


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk