static_cast vs C-style cast in C++: what to choose and why?

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

static_cast, C-style cast and functional notation: battle of the titans in C++

\n\n

Hello, fellow programmer! If you've ever written in C++, you've probably wondered: "Why do all these gurus insist on using static_cast<int>(x) instead of the good old (int)x or int(x)? After all, the result is the same!"

\n\n

Spoiler: the result is not always the same, and the difference can cost you hours of debugging, and sometimes even program safety. In this article, we'll break down a popular Stack Overflow question (with thousands of views) and explain in detail why modern C++ (starting from C++11 and later) strongly recommends using static_cast.

\n\n

We won't just list the rules; we'll show them with live examples you can run. Let's go!

\n\n

1. Visual "noise" and code search

\n\n

The problem with C-style cast

\n\n

Imagine a line of code:

\n\n
int result = (int)someDoubleValue * (int)anotherDoubleValue;
\n\n

How many type casts are here? Two. But try to find them with your eyes in half a second. Now imagine you have 5000 lines of code, and half of them contain such parentheses. It's a nightmare for code review.

\n\n

Now let's look at the same code with static_cast:

\n\n
int result = static_cast<int>(someDoubleValue) * static_cast<int>(anotherDoubleValue);
\n\n

It's immediately obvious: "Aha, here we are deliberately truncating double to int." static_cast acts as a documenting comment. It screams: "I know what I'm doing! This is a conscious type cast!"

\n\n

Bonus for grep and IDE

\n\n

Try to find all places in a project where C-style cast is used. You'll be searching for just ) or ( — that's impossible. But static_cast can be found with a single command grep -r "static_cast". Your IDE will highlight them, and you can quickly scan all dangerous spots.

\n\n

2. Safety: the compiler is your friend, not your enemy

\n\n

Typical beginner mistake

\n\n

Suppose you want to cast a pointer to a base class into a pointer to a derived class. C-style cast will do it silently, even if the class hierarchy is unrelated:

\n\n
class Base { /* ... */ };\nclass Derived : public Base { /* ... */ };\nclass Unrelated { /* ... */ };\n\nBase* basePtr = new Derived;\nUnrelated* badPtr = (Unrelated*)basePtr; // The compiler stays silent!\n// Now you have UB (undefined behavior) when accessing badPtr\n
\n\n

This is called reinterpret_cast, and C-style cast performs it without warning. static_cast will produce a compilation error in such a situation:

\n\n
Unrelated* badPtr = static_cast<Unrelated*>(basePtr); // Compilation error!\n// error: invalid static_cast from type 'Base*' to type 'Unrelated*'\n
\n\n

The compiler is your shield. C-style cast is like turning off all safety systems in a car and hoping you don't crash.

\n\n

Downcasting pointers in a hierarchy

\n\n

C-style cast allows downcasting without runtime type checking. static_cast also allows it, but at least it checks that the classes are in the same inheritance hierarchy. For safe downcasting with RTTI checking, use dynamic_cast — but that's another story.

\n\n

3. Control over what you're doing

\n\n

Three different casts in one set of parentheses

\n\n

C-style cast is a Swiss Army knife that can do three different things:

\n
    \n
  • static_cast (ordinary casting between numeric types or up/down a hierarchy)
  • \n
  • const_cast (removing constness)
  • \n
  • reinterpret_cast (reinterpreting the bit representation)
  • \n
\n\n

Here's an example that shocks many:

\n\n
const                

Blogs

Book Recommendations