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.