The C/C++ casting codundrum.

In C, casting is simple. “See that thing on the right? It’s really a thing on the left.” The compiler was perfectly willing to consider any set of bits as whatever you like. With no inheritance & no casting operators, types generally aren’t related to each other. It was up to the dev to decide when & how to cast around, including casting to void* or casting away const.

In C++, casting got more complex. There seem to be two factors:

· C++ users expect the compiler to help them avoid certain type manipulation SNAFUs as the C++ type rules are stricter than C.

· You can walk up & down inheritance hierarchies with casts, with behind-the-scenes vtable manipulation.

Bjarne, showing once again that thinking in Danish makes you a successful language designer, added casting operators to the language:

reinterpret_cast – take any set of bits and treat them as a different type. Commonly thought to be the C++-way of writing a C-style cast, but it ain’t! C-style casts will walk vtables, but reinterpret_cast will not. Don’t use this one unless you’re 100% sure you have to.

const_cast – take a type an add or remove const-ness. A great addition to the language, because:

1. I won’t accidentially cast to the wrong type in the process

2. I can see where in the codebase we’re breaking const-ness by simply searching for “const_cast”.

static_cast – a lot like a C-style cast, without as many pitfalls. Most casts in my code could become static_cast.

dynamic_cast - use RTTI to safely cast between types. Even safer that static_cast. C++ developers tend to shun RTTI & dynamic_cast due to perf concerns, but I think they are overreacting.

Now I’m happy, right? I can do text searches through my code for specific cast types if I want to refactor them away. The compiler can protect me from accidentally removing const (with static_cast) or accidentally changing a type (with const_cast).

Problem is, my C++ code is full of C-style casts. I don’t know of a good way to find them all. Grep for parenthesis?

Oh C++ compiler team! Hear my plea! Add a warning for C-style casts to the C++ compiler!

Comments

  • Anonymous
    June 18, 2004
    "C-style casts will walk vtables, but reinterpret_cast will not."

    Under what conditions would the C-style cast walk vtables?
  • Anonymous
    June 18, 2004
    And what does "walk vtables" mean?
  • Anonymous
    June 19, 2004
    I was hoping someone else would offer up an answer; guess not.

    If you cast a pointer up or down the inheritance hierarchy, the pointer value is adjusted to point to the correct vtable, if you use an appropriate type of cast.
  • Anonymous
    June 21, 2004
    Hear! Hear! I abhor C-style casts.

    PCLint has such a warning, but it would be SO MUCH nicer if it was supported by the compiler.

    Another benefit of the longish C++ casts is that they could prompt the developer to ask "can I change things to get rid of this cast?" (espcially if they can't do a C-style cast, because Warnings-as-Errors is enabled).

  • Anonymous
    June 22, 2004
    All four links you provide above have the same url.
  • Anonymous
    June 23, 2004
    Jay,

    I know this is probably several days too late. Can you make any assumptions about how the code is formatted? Probably not, but how about an 80% solution? This regex will find a set of parens with a leading space and followed by word character. You can use some variations to get closer to 100%.

    s([^)]*)w
  • Anonymous
    June 23, 2004
    MSDN's web site is annoying. I'll try to fix that when I get some time. Thanks Julien.

    It's never too late! Thanks Ron.
  • Anonymous
    June 24, 2004
    The comment has been removed
  • Anonymous
    June 24, 2004
    Oh, I forgot to mention, it's sloooowww. And the regex I supply by default could use some work.
  • Anonymous
    June 24, 2004
    Thanks for the contributions, and the compliment.