This section of the archives stores flipcode's complete Developer Toolbox collection, featuring a variety of mini-articles and source code contributions from our readers.

 

  A New Cast For C++, With Rating
  Submitted by



Following my previous TOTD thread, I began thinking about what I think are the most important things you need to consider when you're about to implement a technique using something "really smart", especially in C++:

1- The ease of use of the technique. If it's hard to use, it won't be used.

2- The ease of understanding how it works, black-box style. If its functioning is obscure, users will make too many mistakes.

3- The clarity of error messages when users do make mistakes, typos, etc...

4- The ease, for you, of understanding the innards of the technique. If you came, say, a year later, and you had to mess with it, how bad would it be?

5- The ease, for another programmer, of understanding the innards. In case you jump from a plane and forget the parachute, so to speak.

(Am I forgetting anything critical here?)

I believe that, with those things, you can measure the desirability of actually doing it. It should be interesting if we start rating our posts like that.

Anyway, I'd like to post a nice tip. It's not from me, originally. I saw it in a presentation by one of the developers at Microsoft working on the MSVC++ debugger, so the actual credit should go to him. I just don't remember his name. He proposed a new cast, called checked_cast. It would work just as a static_cast, except that it would use dynamic_cast to catch programming errors in debug mode. I modified it somewhat, so it ended up like this:

template < class TypeTo, class TypeFrom 
__forceinline TypeTo checked_cast(TypeFrom *t) {
#if (defined(CHECKED_BUILD) || !defined(NDEBUG))
   if (t) {
     TypeTo dtto = dynamic_cast<TypeTo(t);
     TypeTo stto = static_cast<TypeTo(t);
     ASSERT(dtto != 0);
     ASSERT(dtto == stto);
     return stto;
   } else {
     return 0;
   }
#else
   return static_cast<TypeTo(t);
#endif
} 


If you try to perform an up-cast with checked_cast when in debug mode, it'll assert out. In release mode, it'll assume the cast is correct, and so it performs it in the most efficient manner.

So... how should we rate this? My personal opinion is:

  • 1- Very good.
  • 2- Very good.
  • 3- Very good (MSVC).
  • 4- Very good. (That's for me ;-)
  • 5- Good, I believe. It does require some understanding of templates, though.


  • To test the error message generation I used the following code in MSVC++ 6.0:

    struct A {};
    struct B: A {};

    void func2() { static_cast(8); checked_cast(8); static_cast<2; checked_cast<2; static_cast<2(); checked_cast<2();

    A a; B *pb;

    pb = static_cast<A*(&a); pb = checked_cast<A*(&a);

    pb = static_cast<int*(&a); pb = checked_cast<int*(&a);

    pb = static_cast<int(&a); pb = checked_cast<int(&a);

    pb = static_cast<B(&a); pb = checked_cast<B(&a);

    // Correct form. pb = static_cast<B*(&a); pb = checked_cast<B*(&a); }


    In all cases the message was marked on the proper line of code, and, in all the cases after defining the local variables, I got for static_cast the same error message that I got for checked_cast.

    Salutaciones,
          JCAB

    The zip file viewer built into the Developer Toolbox made use of the zlib library, as well as the zlibdll source additions.

     

    Copyright 1999-2008 (C) FLIPCODE.COM and/or the original content author(s). All rights reserved.
    Please read our Terms, Conditions, and Privacy information.