
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