Boost logo

Boost :

From: Martin Bonner (Martin.Bonner_at_[hidden])
Date: 2007-10-12 04:59:24


From: Simonson, Lucanus J

> Martin wrote:
>> I don't think that's true. Given:
>> class Base {....}
>> struct Derived : public Base{ int DerivedFunction(); };
>>
>> Base b;
>> Derived* pDerived = static_cast<Derived*>(&b);
>>
>> pDerived->DerivedFunction(); // Undefined behaviour.
>> The behaviour of the call to DerivedFunction is not defined by the
>> standard. (Of course, on many compilers today it will do what the
>> author >expected.)
>
> The reason it is categorized as undefined is because Derived may
> extend Base by adding data members, inheriting from another base,
> or adding a virtual pointer.
Partly
> My contention was that the behavior when none of those conditions
> is true is defined, or at least implicitly defined. What I
> mean by implicitly defined is that if X is true, and Y is true then we
> can infer that Z must also be true. This happens in specs all the
> time.

You missed my point about type aliasing. Let's extend the example a
little further (and convert to references because that's what you tend
to use).
        struct Base { int i; };
        struct Derived : Base { void f() { this->i = 5; } };

        Base b;
        b.i = 2;
        Derived &refD = static_cast<Derived&>(&b);
        refD.f();
        b.i -= 2;
At this point a compiler which does value tracking "knows" that b.i is 2
(not 5) and can optimize the last statement to
        b.i = 0;
With most compilers today, that only works because Derived.f() is
inline, and the compiler can see that there is no cast of refD to Base&.
Future compilers may be better at optimizing between modules.

> If I have Base and Derived types the compiler has to ensure correct
> execution when given the clearly standard compliant usage:
>
> Derived object;
> object.do_something();
> Base& baseRef = object;
> base.do_something_else();
> Derived& derivedRef = static_cast<Derived&>(baseRef);
> derivedRef.do_yet_a_third_thing();
>
> ergo it must implicitly support:
>
> Base base;
> base.do_something_else();
> Derived& derivedRef = static_cast<Derived&>(base);
> derivedRef.do_yet_a_third_thing();
>
> provided that Derived does not modify Base by multiple inheritance,
> adding a member or a virtual pointer, because it can't prove that
> derivedRef is not an alias for the pointer to base because it could be
> that derivedRef is an alias for baseRef as part of the standard
> compliant usage.

Well yes it CAN prove that derivedRef is not an alias for baseRef in
your second example - it can /see/ that derivedRef is not an alias for
baseRef.

> If a compiler optimization can be proven to break standard compliant
> code it is safe to assume that such compiler optimization won't
> happen, or at least will be rolled back immediately.

but how about a compiler optimization that /won't/ break standard
compliant code, but /will/ break your code?

-- 
Martin Bonner
Senior Software Engineer/Team Leader
PI SHURLOK LTD
Telephone: +44 1223 441434 / 203894 (direct)
Fax: +44 1223 203999
Email: martin.bonner_at_[hidden]
www.pi-shurlok.com
disclaimer

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