Explicit Type Conversion
Avoiding C-style casts changes how a conversion is written, not whether the conversion happens. A program that needs a conversion still needs it after the rewrite.
A Cast That Looks Harmless
Many programmers reach for a short, parenthesized prefix when they need one type to be treated as another. That short form is the C-style cast. It works, it is compact, and it appears in a great deal of older code, so it is easy to assume it is an acceptable default. The guidance in this part of the material takes the opposite view: programmers should seriously consider banning C-style casts from their own programs. This article looks at why that advice exists and what to write instead.
What do you think happens?
Suppose two versions of the same conversion are equally correct in what they produce. Which one should a careful team prefer?
Reveal answer
The named cast that states the conversion in the code
Both versions produce the same value, so the difference is not correctness. The named form announces the conversion through its name, so a reader can see and find it. The short form hides that intent inside a compact prefix.
Why the Short Form Is Tempting
The common belief is that a C-style cast is simply the normal way to force a conversion, and that nothing is lost by using it. The reasoning behind the guidance is more specific than a general dislike of casts. The concern is about how the conversion is written, not whether it should happen at all.
Avoiding C-style casts changes how a conversion is written, not whether the conversion happens. A program that needs a conversion still needs it after the rewrite.
Tracing What a C-Style Cast Hides
A C-style cast names the target type inside parentheses and then places the expression after it. When a reader sees a line like that, the compact form tells them that a conversion is happening, but it does not say which kind of conversion the programmer intended. The reader has to reconstruct that decision from the surrounding types, which is harder when the code is long or unfamiliar.
The diagram shows the gap. The written form carries the target type and the expression, but the kind of conversion is left for the reader to work out. Named casts close that gap by putting the kind of conversion into the name itself.
Reading the Two Forms Side by Side
The example below converts a double to an int in two ways. The first line uses a C-style cast. The second uses a named cast. Both lines discard the fractional part, so both print the same number. The difference lies in what a reader sees on each line.
3 3- Line 5: the C-style cast writes the target type in parentheses before the value
- Line 6: the named cast writes the same conversion with an explicit operator name
In the short form (int)reading, the target type and the expression are still present, but the kind of conversion has no name. The named form makes the three parts visible: the operator, the target type in angle brackets, and the expression in parentheses. The rewrite does not change what the conversion produces. It changes what the line says.
Tracing a Value Through the Conversion
Converting 3.7 into an int
A double holding 3.7 is converted to an int using a named cast. What value does the int receive, and what happens to the fractional part?
- 1Start with the declared value
The variable reading is a double with the value 3.7.
- 2Apply the named cast
static_cast<int>(reading) requests a conversion from double to int. The target type is written in the angle brackets. - 3Discard the fractional part
The fractional part .7 is removed, leaving the whole-number part 3.
- 4Store the result
The int variable b receives 3, which matches the output of the earlier example.
The int holds 3. The conversion is explicit in the code, and the fractional part is dropped by the conversion.
Named Casts as Searchable Intent
In C++, the named casts are the operators whose names describe the kind of conversion being requested, such as static_cast. Writing the cast with a name means the conversion is announced in the code itself. A reader scanning the program can locate every such conversion, which is the visibility the guidance is pointing to. Named casts are preferred because they are more explicit and more visible than C-style casts.
| Aspect | C-style cast | Named cast |
|---|---|---|
| Written form | (int)value | static_cast<int>(value) |
| Conversion is announced in the code | Not by a name | Yes, by the operator name |
| Easy to find when reviewing | Hard to search for | Can be located by its name |
| Intent visible to a reader | Must be inferred | Stated directly |
| Produces the same value in the example | Yes | Yes |
Both forms can express the same conversion, but the named form makes the programmer's intent visible.
The visibility point matters during code review. A reviewer who wants to check every conversion in a module can search for the named operator and find each one. Searching for a compact parenthesized prefix is far less reliable, because parentheses appear throughout ordinary code for many unrelated reasons.
Mistakes When Moving Away from C-Style Casts
Common mistake Removing the cast and expecting the conversion to disappear
What it looks likeint a = reading; with reading as a double, written without any castWhy it failsAvoiding C-style casts changes how a conversion is written, not whether it happens. The conversion still occurs, but it is no longer stated explicitly.
Do this insteadKeep the conversion and write it with a named cast, such as static_cast<int>(reading), so the intent is visible.
Common mistake Assuming the two forms always produce different results
What it looks likeComparing (int)reading and static_cast<int>(reading) and expecting different output
Why it failsBoth forms are explicit conversions of the same value. In the source example both discard the fractional part and print the same number.
Do this insteadJudge the forms by explicitness and visibility, not by the value they produce in a single case.
Common mistake Treating the goal as banning every type conversion
Why it failsThe source's point is that where explicit conversion is necessary, named casts can do what a C-style cast can.
Do this insteadBan the unnamed form, and use named casts for the conversions the program truly needs.
Rewriting a Cast by Hand
Rewrite the following C-style cast using a named cast so that the conversion is visible in the code: double ratio = 7.9; int whole = (int)ratio;
Hints
- Identify the target type, which is int, and the expression being converted, which is ratio.
- Use the named cast
static_cast, placing the target type in angle brackets and the expression in parentheses. - The fractional part of 7.9 is discarded, so whole should still hold 7.
Key Takeaways
- C-style casts are a form of explicit type conversion that the source advises programmers to seriously consider banning from their own programs.
- Avoiding C-style casts changes how a conversion is written, not whether the conversion happens.
- Where explicit conversion is necessary, a combination of named casts can do what a C-style cast can.
- Named casts such as
static_castare preferred because they are more explicit and more visible, so a reader and a reviewer can find each conversion by its name.