← Back to team overview

kicad-developers team mailing list archive

Re: Style question: static vs dynamic cast

 

On 04/19/2014 05:25 AM, Lorenzo Marcantonio wrote:
> Just to know what is the preferred idiom in this place...
> Often a downcast is needed (example: TRACK -> VIA) for obvious reasons;
> 
> I've seen all of the three kind of casts in use around
> a) (VIA*)track
> b) static_cast<VIA*>( track )
> c) dynamic_cast<VIA*>( track )
> 
> a) is the brutal classic C cast (more or less deprecated in C++, but who
>    cares, it (usually) works :D)
> b) is the modern static cast (compiler enforces that it makes sense)
> c) is the modern dynamic cast which at runtime uses RTTI to check the
>    actual classes and returns null if mismatched
> 
> Most of the time we actually use Type() to check the instance type,
> since there is this pre-RTTI information available. After that, either
> of the three cast is acceptable. So the usual pattern in use is:
> 
> if (t->Type() == PCB_VIA_T) {
>     VIA *via = (VIA*)t; // Or static_cast for the C++ way
>     // do stuff with via
> }
> 
> ...which is obviously correct if Type() is immutable and can't be
> corrupted (this is hope :D)
> 
> AFAIK (see http://en.cppreference.com/w/cpp/language/static_cast) this
> downcast is fine unless we introduce some virtual parent (it has to do
> to the object layout in memory, IIRC). The same should be valid for the
> C cast, too.
> 
> As a rule I personally prefer a dynamic_cast for downcasting (and
> eventually an assert after it, to be sure). It also permit the more
> C++-ish idiom:
> 
> VIA *via = dynamic_cast<VIA*>(t);
> if (via) {
>     // do stuff with via
> }
> 
> i.e. using the builtin RTTI. However I agree that dynamic_cast is not
> free (it has a checking on the order of the Type() one, I presume), and
> not everyone likes defensive programming (most of the people coming from
> a background where software bugs makes things go boom... even if usually
> they don't want C++ if things *could* go boom)
> 
> So, which is the 'preferred' idiom in kicad?

For me it seems context specific, and I would not feel comfortable saying one strategy
fits all contexts.  A dynamic cast has to be about 100 times slower than a C style cast,
and therefore you would not use that unless you can afford the hit.

Bugs should be caught in the Debug build, so if you wanted to pay for the cost in that
build, but not in the Release build, one idea to check the caller's argument would be:

wxASSERT( dynamic_cast<TARGET*>( arg ) );
p = (TARGET*) arg;


This checks for NULLness and class hierarcy.  IF the caller has a problem in the Release
build it will be there in the Debug build.  Once these are caught, there is no reason to
pay for this at runtime.  In variably, (pun in intended) the problem will be with the
caller, but even then its hard to get that wrong with type checking for every argument to
every function.

I can only imagine that when you are coming from a generic pointer type like void* that
this is a real aid.

Dick









Follow ups

References