[haiku-commits] Re: r38086 -DA haiku/trunk/src/servers/app/drawing/Painter

  • From: Ingo Weinhold <ingo_weinhold@xxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Fri, 13 Aug 2010 18:33:53 +0200

On 2010-08-13 at 16:38:01 [+0200], Rene Gollent <anevilyak@xxxxxxxxx> wrote:
> On Fri, Aug 13, 2010 at 9:56 AM, Ingo Weinhold <ingo_weinhold@xxxxxx> wrote:
> > Multiple inheritance as such isn't be a problem for static_cast -- the
> > pointer is adjusted just the same. Virtual inheritance might be problem,
> > but I guess the compiler would complain in that case.
> 
> Oh? I was always under the impression that static_cast was more or
> less C++ sugar for a classic C-style (type) cast, which does no
> adjustment while dynamic_cast did all the necessary
> checks/adjustments, hence being a slower op. If that's the case, then
> what's the distinction?

static_cast is a compile time cast, i.e. the pointer offset is computed at 
compile time. At run time the operation consists of a NULL pointer check and 
an addition of the (hardcoded) offset. The obvious requirement for the 
applicability of static_cast is that the two involved classes are related. 
You can static_cast between BNode* and BFile* (both directions), but not 
between BNode* and BPositionIO*, regardless of whether the object is a BFile. 
Unless the given pointer is NULL, static_cast always succeeds, even, if the 
object is actually not of the target type (e.g. BNode* -> BFile* works also 
for BSymLink objects).

dynamic_cast is a run time cast, i.e. -- maybe with the exception of simple 
up casts (BFile* -> BNode*) -- it always uses RTTI. This imposes the 
requirement that the source type must be run time polymorphic (must have a 
vtable). The target type can be any type, and the cast will succeed, if and 
only if the casted object is of that type (directly or indirectly). That is 
cross casts (BNode* <-> BPositionIO) are possible.

If one is certain of the object's type and source and target type are 
related, static_cast is fine. If one is certain but paranoid (and performance 
isn't a concern) dynamic_cast might be the better choice, since it would 
result in a straight forward NULL pointer crash instead of possibly weird 
behavior. If the object type is uncertain, dynamic_cast with an explicit 
result check is mandatory.

C cast is static_cast, reinterpret_cast, and const_cast rolled into one. The 
const_cast is implicit. Other than that the C cast is behaviorally equivalent 
to static_cast in all cases where static_cast could be applied (i.e. the 
types are related). Otherwise it works like reinterpret_cast, i.e. BNode* <-> 
BPositionIO conversions aren't criticized by the compiler, but they yield 
incorrect results.

CU, Ingo

Other related posts: