TITLE: old and new style casts (Newsgroups: comp.std.c++, 3 Sep 97) IRELAND: Matthew Ireland > A discussion has come up at work about casting. When I learned C++ > there were two methods of casting available, the old c way: > (int)SomeNumber > and a new c++ way > int(SomeNumber) CLAMAGE: Steve Clamage That is approximately correct. The "new" style goes back to very early versions of C++. The two forms were allowed because neither form alone could perform all possible C++ casts. To cast to a type which whose name is not a single identifier, only the traditional style can be used: (char*)i // OK char*(i) // syntax error To cast to a class type whose constructor takes more than one argument, only the added style can be used: myclass(i, j, k) // OK (myclass)i, j, k // wrong, possibly invalid The fundamental problems with casts remained, in particular: 1. Casts are used for a variety of purposes -- navigating in a class hierarchy, value conversion, non-portable conversion, type punning. You can't tell from looking at the cast what its purpose might be. 2. You can't use a text editor to locate casts in a program. You need a complete C++ parse of the code, and a browser that can be told to look for casts. Since casts always should be examined when porting a program, being unable to find casts easily is a real hinderance to reliable programming. IRELAND: > Now I have been told that both of these are replaced by > > static_cast< typeid >( expression ) > dynamic_cast< typeid >( expression ) > const_cast< typeid >( expression ) > reinterpret_cast< typeid >( expression ) > > which seems to me to be overkill when I am just trying to make sure that > any promotion done to do a calculation or some constant is in the form I > want it to be. CLAMAGE: Certainly it means more text to write and read, but that was intentional. Nearly all safe conversions are implicit in C++, and no explicit cast needs to be written. If you write a necessary cast, it means you are doing something potentially dangerous or non-portable. The syntax ought to reflect the magnitude of what you are doing. (At least, that was the reasoning -- you don't have to agree.) In addition, it is easy to make a mistake in an old-style cast -- accidently casting away const, or casting to an unrelated pointer type instead of within a hierarchy. Further, a cast may be originally valid but may become incorrect (but still legal) when types are modified. The compiler won't help you find these errors. The new-style casts, on the other hand, state what you are trying to accomplish. People reading your code can tell why you are performing a cast. The compiler will catch most kinds of unintended use of the cast and flag the error. Unfortunately, there is still one kind of legitimate cast which is not allowed by new-style casts: casting from a derived class to a private base class. You must still use an old-style cast for that purpose. (At least, if a proposal to fix this omission was accepted, I missed it.) In your example, setting the type of intermediate calculation result, static_cast would be the appropriate new-style cast. Using an old-style cast would probably not be any less reliable.