Synopsis: | Use the new cast operators (static_cast, const_cast, dynamic_cast, and reinterpret_cast) instead of the C-style casts |
Language: | C++ |
Severity Level: | 1 |
Category: | Conversions |
Description: |
Let's assume these: class CMyClass : public CMyBase {...}; class CMyOtherStuff {...} ; CMyBase *pSomething; // Filled somewhere Now, these two are compiled the same way: CMyClass *pMyObject; pMyObject = static_cast<CMyClass*>(pSomething); // Safe; as long as we checked pMyObject = (CMyClass*)(pSomething); // Same as static_cast<>. Safe; as long as we checked, but harder to read However, let's see this almost identical code: CMyOtherStuff *pOther; pOther = static_cast<CMyOtherStuff*>(pSomething); // Compiler error: Can't convert pOther = (CMyOtherStuff*)(pSomething); // No compiler error. Same as reinterpret_cast<> and it's wrong!!! As you can see, there is no easy way to distinguish between the two situations without knowing a lot about all the classes involved. The second problem is that the C-style casts are too hard to locate. In complex expressions it can be very hard to see a C-style cast. It is virtually impossible to write an automated tool that needs to locate C-style casts (for example a search tool) without a full blown C++ compiler front-end. On the other hand, it's easy to search for "static_cast<" or "reinterpret_cast<". pOther = reinterpret_cast<CMyOtherStuff*>(pSomething); // No compiler error. // but the presence of a reinterpret_cast<> is // like a Siren with Red Flashing Lights in your code. // The mere typing of it should cause you to feel VERY uncomfortable. That means that, not only are C-style casts more dangerous, but it's a lot harder to find them all to make sure that they are correct.
See also [CON#006] for a discussion about the new cast operators. Since conversion functions for built-in types such as behave exactly the same as C style casts, these aren't allowed either: a = int(b); // Wrong, is the same as a = (int) b; Exception to this rule: Using (void) to cast-away the return value is allowed. |
Literature References: |
StackOverflow Q103512 |