20 Comments

  1. Rich

    Why no in the static_cast used in non-const ‘getAt’ function (in the example for const_cast)? I have not seen that usage before.

    Reply
    1. Arne Mertz

      I have to confess I don’t fully understand the question. If you meant the missing `< MyContainer const*>` after the `static_cast`, then this was simply a rendering problem in the code formatting plugin.

      Reply
      1. Rich

        I see it’s fixed now. Yes, when I viewed it, the was not there after static_cast.

        Reply
        1. Rich

          Hmm. My comment got altered. Yes, the type that you added now appears. No confusion now.

          Reply
          1. Arne Mertz

            Yeah I noticed that things with angle brackets sometimes are interpreted as maybe-html-tags that don’t get printed.

    2. Rich

      p.s. Thanks for finding me on Twitter. Like the blog!

      Reply

  2. Hey Arne, great article!

    What do you think about wrapping existing casts in stricter ones?
    I gave a lightning talk about this at Meeting C++ 2016.
    (https://www.youtube.com/watch?v=62c_Xm6Zh1k)

    I think “thin wrappers” which are stricter and do as much checks as possible at compile-time (also assertions) are a good idea to make the code safer and more readable, and also to clearly express your intentions.

    My code is here if you want to take a look:
    https://github.com/SuperV1234/meetingcpp2015/tree/master/0_MeaningfulCasts

    Thankfully, boost (and probably other mature libraries) also provide their “cast wrappers” for numbers and class hierarchies.

    Reply

  3. Hi Arne!

    Maybe you should additionally add (from the new standard for casting of std::shared_ptr’s):

    * const_pointer_cast
    * static_pointer_cast
    *dynamic_pointer_cast

    kind regards,
    Christian

    Reply
    1. Arne Mertz

      Hi Christian,
      thanks for the suggestion. This post was at the time purely targeted at built in casts. I will cover the ones you mentioned in a post about shared_ptr in the future.

      Reply

  4. Martin Ba

    Wrt. reinterpret_cast : I use it when converting btw. char* and anyIntegralType*, that is when casting an int buffer to a char buffer. Using reinterpret_cast directly seems much clearer to me that the other option of doing two static casts via void* (see, e.g. http://stackoverflow.com/questions/24626972/reinterpret-cast-vs-static-cast-for-writing-bytes-in-standard-layout-types).

    The only annoying thing is that casting int* to char* via reinterpret_cast is virtually guaranteed to be a safe operation, while casting char* to int*, even if the buffer contents are good, can invoke UB due to alignment issues.

    Personally I feel that rather than explaining what reinterpret_cast does or does not, we need to look very hard at what it is still used and needed for and come up with safer wrapper functions. (See e.g. http://stackoverflow.com/a/27237839/321013)

    Reply
  5. Marcel

    Your example for const_cast is seriously flawed: It’s the non-const version which should call the const one. Otherwise changing the implementation of the non-const version may break const correctness.

    class MyContainer {
      int* data;
    public:
      int& getAt(unsigned index) {
        return const_cast(static_cast(*this).getAt(index));
      }
      const int& getAt(unsigned index) const {
        checkIndex(index);
        return data[index];
      }
    };
    
    Reply
    1. Arne Mertz

      Thanks for pointing that out. Fixed!

      Reply
      1. Andrea Bigagli

        Uhu? I still see a couple of errors in the code snippet:

        1) the const version of getAt returns “int&” instead of “int const &”
        2) the non-const version of getAt is missing a “static_cast(this)” when delegating to the const version of getAt, which would result in infinite recursion.

        Maybe something didn’t work with updating the snippet or my browser is playing (caching) tricks on me?

        Reply
        1. Arne Mertz

          The thing that did not work when updating the snippet was my brain 😉 I hopefully fixed it now.

          Reply

  6. Nice post! Very good overview of casts.

    Also, I would add a point that in some cases you can’t implicity add ‘const’ to type. For example:

    class Test {};
    
    Test* t;
    const Test ct;
    Test ** t1 = &t; //OK
    Test const ** t2 = t1; //ERROR. Should use Test const * const *
    
    //Otherwise you could do something like this:
    *t2 = &ct;
    //Now you can modify const ct object through the t pointer
    Reply
    1. Arne Mertz

      Hi Evgeny, thanks for your comment. I would consider your example an edge case or rather a purely academic case. To be honest, I have never come across a situation where a pointer to pointer was needed, or useful, and I can’t think of a situation where they should be used. In fact, I would strongly advise against it, since the double indirection adds complexity that should be avoided.

      Reply

      1. Sure, it’s generally not very common to see code like this. In my practice I met similar case when was working with a little out-dated API which was receiving array of strings as char const **.

        Reply
        1. Arne Mertz

          Wrap that API so it does not leak the **’s, then dealing with them is a one-time problem 😉

          Reply

Leave a Reply

Your email address will not be published. Required fields are marked *