|
Boost : |
From: Fernando Cacciola (fernando_cacciola_at_[hidden])
Date: 2007-10-10 18:04:42
Hi Lucanus,
> This doesn't convince me that it isn't safe, just that it might not be
> safe, which we already knew.
>
But if something "might not be safe", isn't it almost as bad as being
definitely
not safe?
IOWs, what's the value of safety if it isn't guaranteed?
> 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?
>
But this is the call of the compiler.
As long as the standard doesn't force compilers to guarante that a static
(witout RTTI) cast from base to derived preserves the pointer value, your
presumption is, well, just a presumption.
> I don't for a minute believe that the behavior I am relying upon is
> unspecified or undefined.
> It is specified in the compiler
^^^^^^^^^^^^^^^^^^^^^^^^
Exactly!
Behaviour specified by the compiler, as opposed to the standard, is called
"unspecified", and you shouldn't rely on it unless there is a compelling
reason. I still don't see any.
> , and all
> the compilers
...that you have tested it on...
> somehow managed to agree on the definition and specify
> it the
> same way.
Indeed. This is why if there is a compelling need, you can rely on
unspecified behaviour (with the presumption that the actual behaviour
matches some reasonable choice, like contiguous allocation of vector
elements for instance)
(we are not talking about undefined behaviour).
But then your are at risk that a new complier/compiler version comes alone
and, oh, your library suddenly stops working.
I'll give you a concrete example:
When VC8.0 was first released we discovered that CGAL was misserably
failing, if tested in debug mode, lots of cases that passed with VC7.1 and
all other major compilers.
When I investigated the issue I discovered the following pattern in the
code:
Some_iterator null ;
Some_iterator get_something()
{
if ( cant_do_it )
return null ;
}
Some_iterator result = get_something();
if ( result != null )
use_it(result);
VC8.0 crashes in debug mode, yet not in release mode, when that code is
executed.
Do you see the probem?
Simple, a default constructed iterator (like null there) is a singular
iterator.
And is undefined behaviour to compare two singular iterators.
Yes. Even THOSE two singular iterators in spite of the fact that the
comparisons involved only copies of the object "null".
This pattern was expected to work even in the prescence of a singular
internal value for "null" (it could be anything, not neccesarily a
null-pointer-value).
But no.
VC8, in debug mode, purposedly flagged the iterators as singular and refused
right up front to compared them, because acording to the standard, is
illegal to do that.
..
Anyway, I'm loosing focus, so let's rewing a bit... this all started when
you explained how you don't need to copy the adaptee.
Can you show us in as much detail as possible how do you do that with a very
concrete example?
Say I have:
struct MyPoint { x,y} ;
MyPoint p ;
and I want to call
GTL::foo(p);
with the BGL-style of adaptation I write exactly that line (this is what
Joel means when he says that you can pass user types AS-IS).
What would I need to do in GTL?
And, MORE importantly, what does GTL do, exactly, to adapt my "p" objet
there?
Best
Fernando Cacciola
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk