Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

C++ Casting & Conversions — The One-Stop Guide (up to C++26)

A from-scratch guide to every kind of type conversion in C++: implicit conversions, the four named casts (static_cast, dynamic_cast, const_cast, reinterpret_cast), C-style and functional casts, std::bit_cast, smart-pointer casts, and the subtle pointer-adjustment rules that trip up even experienced engineers. Written for someone comfortable with intermediate C++ who wants to never be confused by a cast again.


Who this is for

You know C++ (classes, inheritance, pointers, references, templates at a basic level) but you're fuzzy on which cast to use when, why dynamic_cast needs a vtable, why reinterpret_cast<Derived*>(base) is a silent bug under multiple inheritance, or what std::bit_cast buys you over a memcpy. By the end you will:

  • Understand the conversion model of C++: what happens implicitly, and why casts are the explicit override of those rules.
  • Know exactly what each of the four named casts can and cannot do — with the compiler's-eye view of what machine-level work (if any) each performs.
  • Read and reason about pointer adjustment under single, multiple, and virtual inheritance (the this-pointer offset problem).
  • Use dynamic_cast correctly (and know when RTTI is the wrong tool).
  • Use std::bit_cast / std::start_lifetime_as for well-defined type punning instead of undefined-behavior tricks.
  • Cast smart pointers (static_pointer_cast, dynamic_pointer_cast, …) safely.
  • Recognize the handful of casts that are undefined behavior and avoid them.

How to read this guide

Read 0005 in order the first time — the named casts build on the conversion model. After that, dip into whatever you need.

# File Topic
00 00-why-casting.md The conversion model; why C casts are dangerous; the 4 named casts overview
01 01-implicit-conversions.md Standard conversions, integral/float promotions, user-defined conversions, explicit
02 02-static-cast.md static_cast — the workhorse: numeric, up/down-cast, void*, enums, std::move
03 03-dynamic-cast.md dynamic_cast, RTTI, vtables, cross-casts, typeid, the reference-throws rule
04 04-const-cast.md const_cast — adding/removing const/volatile, when it's UB
05 05-reinterpret-cast.md reinterpret_cast — bit reinterpretation, strict aliasing, the danger zone
06 06-c-and-functional-casts.md C-style (T)x, functional T(x), what they actually expand to
07 07-pointer-adjustment.md The this-offset problem: multiple & virtual inheritance, why casts move pointers
08 08-bit-cast-and-punning.md std::bit_cast, memcpy, unions, strict aliasing, start_lifetime_as (C++23)
09 09-smart-pointer-casts.md static_pointer_cast, dynamic_pointer_cast, const_pointer_cast, reinterpret_pointer_cast
10 10-narrowing-and-numeric.md Narrowing, {}-init, signed/unsigned, float↔int, std::in_range, gsl::narrow
11 11-patterns-and-pitfalls.md Decision guide, real bugs, anti-patterns, code review checklist
12 12-cheatsheet.md One-page quick reference / decision tree

Runnable examples live in examples/ with a build_all.sh script.


The single most important takeaway (read this now)

 +----------------------------------------------------------------------------+
 |  PREFER NO CAST.  A cast is you telling the compiler "trust me, I know     |
 |  more than you." Every cast is a place a future bug can hide.              |
 |                                                                            |
 |  WHEN YOU MUST CAST, use the NAMED cast that expresses the LEAST power:    |
 |                                                                            |
 |    static_cast       related types, numeric, up/down-cast (no RTTI)        |
 |    dynamic_cast       safe polymorphic down/cross-cast (checked at runtime)|
 |    const_cast         ONLY add/remove const / volatile                     |
 |    reinterpret_cast   raw bit reinterpretation (last resort, often UB)     |
 |                                                                            |
 |  NEVER use a C-style cast (T)x in C++: it silently picks the most          |
 |  dangerous interpretation, including reinterpret_cast + const_cast.        |
 +----------------------------------------------------------------------------+

Why four named casts instead of one C cast?

        C-style cast  (T)expr                Named casts (C++)
        ------------------------             ----------------------------------
        ONE syntax that tries, in order:     FOUR syntaxes, each does ONE job:

          1. const_cast                        const_cast<T>       -> constness
          2. static_cast                       static_cast<T>      -> conversions
          3. static_cast + const_cast          dynamic_cast<T>     -> checked poly
          4. reinterpret_cast                  reinterpret_cast<T> -> raw bits
          5. reinterpret_cast + const_cast

        Problem: (T)x is UNSEARCHABLE and picks silently. If a refactor changes
        the type of x, a (T)x that was a harmless static_cast can BECOME a
        reinterpret_cast with ZERO warning. Named casts fail to compile instead.

Each named cast is:

  • Searchable — you can grep for reinterpret_cast to audit the scary ones.
  • Intent-revealing — the reader knows what class of conversion is happening.
  • Minimally powerful — the compiler rejects misuse instead of silently doing something more dangerous.

Prerequisites & compiler flags

  • Intermediate C++: classes, inheritance, virtual functions, references, const, basic templates and smart pointers.
  • A C++17 compiler for most chapters; C++20/23 for std::bit_cast, std::start_lifetime_as, std::in_range.
g++     -std=c++23 -Wall -Wextra -Wold-style-cast file.cpp   # GCC
clang++ -std=c++23 -Wall -Wextra -Wold-style-cast file.cpp   # Clang

-Wold-style-cast warns on every C-style cast — turn it on and keep your code free of them.


Start with 00-why-casting.md.

About

cpp casting related stuff

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors