Eliminate old C-style casts in C++

The C++ named casts such as static_cast, dynamic_cast, and reinterpret_cast are preferred in C++ Core Guideline ES.49 over ambiguous old C-style casts. C++ named casts can help provide type safety by making the intention of the cast explicit / readable. C++ compilers can detect and warn about improper or unsafe casts when using named casts. C-style cast mistakes are more difficult to detect by humans or automated tools.

static_cast is used for conversions between compatible types, such as converting an int to a float or a pointer to a base class to a pointer to a derived class. Another common static_cast use case is interfacing with C functions such as Windows API functions that require specific types less common in pure C++ code.

int a = 10;
float b = static_cast<float>(a);

reinterpret_cast is used for low-level reinterpreting of bit patterns. It casts a type to a completely different type. This cast is not type safe and should be used with caution to avoid undefined behavior. reinterpret_cast is commonly used in low-level programming, such as interfacing with hardware or converting between pointers and integers.

int a = 10;
char* b = reinterpret_cast<char*>(&a);

dynamic_cast is used for safe downcasting of pointers or references to classes in a class hierarchy. It performs a runtime or RTTI check to help ensure that the cast is valid. dynamic_cast is used when you need to convert a pointer or reference to a base class to a pointer or reference to a derived class. static_cast is more common and faster than dynamic_cast, but dynamic_cast is safer when downcasting in a class hierarchy.

Detecting Old-Style Casts with GCC or Clang

To ensure that old C-style casts are not used in a codebase, consider the -Wold-style-cast flag with GCC or Clang. This flag generates warnings for any old-style casts found in the code.

In CMake, this flag is applied like:

dd_compile_options("$<$<COMPILE_LANG_AND_ID:CXX,AppleClang,Clang,GNU>:-Wold-style-cast>")

If the CMake variable CMAKE_COMPILE_WARNING_AS_ERROR is set true, the old-style cast warnings (and other compile warnings) will be treated as errors.