35

I am well aware of the advantage in using static_cast rather than C-style casting for pointer types.

If the pointer types are incompatible, then:

  • static_cast will yield a compile-time error at a specific line within the source code
  • C-style casting might lead to a runtime error at a "random" point in the execution of the program

But I am unable to find any similar example for non-pointer types.

In other words, both casting methods yield the same result for non-pointer types.

Is that correct, or have I missed anything?

If yes, is static_cast used for non-pointer types only in order to maintain coding consistency?

barak manos
  • 29,648
  • 10
  • 62
  • 114
  • 5
    A C-style cast doesn't care whether input or output are a pointer. It will happily convert between pointers and non-pointers. – Ulrich Eckhardt Dec 17 '14 at 12:26
  • I found a nice explanation [here](http://en.cppreference.com/w/cpp/language/explicit_cast). – TobiMcNamobi Dec 17 '14 at 12:44
  • 2
    @Dinal24: It doesn't refer to my specific question regarding the advantages of `static_cast` over regular cast in the case of **non-pointer types**. – barak manos Dec 17 '14 at 12:55
  • 3
    Item 2 in Scott Meyers' most excellent `Effective C++` book has a dedicated section labelled "Prefer C++-style casts" about this exact topic. – Frerich Raabe Dec 17 '14 at 12:57
  • @rubenvb: It doesn't refer to my specific question regarding the advantages of `static_cast` over regular cast in the case of **non-pointer types**. – barak manos Dec 17 '14 at 13:02
  • 1
    I don't think this is a duplicate of [this "canonical" question](http://stackoverflow.com/questions/28002/regular-cast-vs-static-cast-vs-dynamic-cast?lq=1). The answer to this question can be deduced from the one to the general one, but is not explicitly stated there. – Angew is no longer proud of SO Dec 17 '14 at 13:04
  • @Angew: Thanks. Can you please reopen it? – barak manos Dec 17 '14 at 13:04
  • 1
  • 3
    Well, the answers given here are *exactly* the same as for both other duplicates. Apart from an explicit "yes". Although [this answer](http://stackoverflow.com/a/332086/256138) specifies exactly why you'd prefer C++ style casts for everything... – rubenvb Dec 17 '14 at 13:22

4 Answers4

33

One advantage which the other two answers didn't mention yet is that static_cast is much easier to spot. The meaning of parentheses is notoriously overloaded in C++ and it can be difficult to spot evil (or even incorrect) casts. When I see something ending in _cast though, it's like a mental speed bump: I slow down and carefully check why the type system is being subverted.

Frerich Raabe
  • 90,689
  • 19
  • 115
  • 207
  • 11
    Readability... sometimes far more important than the technical reasons. – Michael Gazonda Dec 17 '14 at 12:50
  • 4
    Readability and easy visual spotting are nice, but the real big advantage of static_cast over c style cast shows with CTRL+F. Have you ever tried to find all existing c style casts in a major part of your codebase? – Kaiserludi Dec 17 '14 at 18:43
  • @Kaiserludi I suppose 'readability by tools' could also be considered 'readability'. – Frerich Raabe Dec 18 '14 at 09:27
  • Er... This is not exactly as clear cut as it seems to be. The whole point of introducing C++-style casts is to distribute various responsibilities among different kinds casts instead of piling them all up onto C-style cast. However, even after that distribution, `static_cast` still appears to be doing too much. It covers two completely unrelated areas: non-trivial pointer casts (hierarchical upcasts and casts from `void *`) as well as arithmetic casts. Doing them all through `static_cast` actually makes them *harder* to spot. – AnT stands with Russia Dec 25 '16 at 07:57
  • I want a clear visual distinction between the former and the latter. I want `arithmetic_cast` as a separate kind of cast. But I want it to have a more compact name than a full blown `arithmetic_cast` (that would be unwieldy). This is where C-style cast fits in very nicely. C-style cast is for arithmetic casts, `static_cast` is for pointer casts. They are harder to spot, you say? I don't remember having any need to deliberately spot arithmetic casts. Pointer casts - yes, but not arithmetic casts. Arithmetic casts are natural. They are not supposed to be more "spottable" than, say, `+` operator. – AnT stands with Russia Dec 25 '16 at 08:00
17

I'm assuming that trivial uses of references to avoid pointers won't count.

In that case: a C-style cast can be:

  • a const_cast
  • a static_cast
  • a static_cast followed by a const_cast,
  • a reinterpret_cast
  • a reinterpret_cast followed by a const_cast

with the exception that static_cast's restrictions on inaccessible base classes are lifted.

const_cast only applies to pointers and references.

reinterpret_cast only applies to pointers and references. It does include pointer-to-integer conversions and vice versa, but that still involves a pointer type.

That special exception for static_cast only applies to pointers and references.

So yes, by excluding pointers and references, you've excluded everything that C-style casts support over a static_cast.

If yes, is static_cast used for non-pointer types only in order to maintain coding consistency?

Let's go with an analogy: I wouldn't use a chainsaw to open a bag of chips. I could, but chainsaws are dangerous, so by using one, I'd introduce unnecessary risks. It's very easy to use a chainsaw wrong, and if I do use it wrong, there's no safety mechanism to prevent accidents.

  • 2
    A more vivid version of your analogy: you certainly can cut your toenails with a chainsaw, but you better know what you're doing. – Frerich Raabe Dec 17 '14 at 12:49
  • 1
    @FrerichRaabe On the other hand, if you know what you're doing, you won't be cutting your toenails with a chainsaw. :) –  Dec 17 '14 at 12:50
  • 3
    The proper metaphor is that you should be damn sure it's a bag of chips which you open with your flame thrower instead of a knife, and not a bag of popcorn or dynamite which would blow up in your face, to varying degrees. – Peter - Reinstate Monica Dec 17 '14 at 12:56
  • @PeterSchneider Heh, that sounds good. It works with chainsaws too: you'd better not use a chainsaw as an alternative to taking the lid off of a glass jar. –  Dec 17 '14 at 14:46
16

Is static_cast used for non-pointer types only in order to maintain coding consistency?

Not only that, but also to help maintain correctness and future compatibility.

It helps maintain correctness, since static_cast cannot do some casts which a C-style cast can. This helps if you make a mistake about some of the types involved, perhaps handling a pointer while being convinced it's an integer (and down several layers of templates and typedefs, that's not too difficult to imagine). So if you intend a static_cast, write one and get a compile-time error, you'll be told immediately that the types involved are not what you thought they were. With the C-style cast's "anything goes" attitude, you will not discover the mistake in time.

It also helps with future compatibility. If the types involved in the cast change later in the development, a static_cast will report an error where a C-style cast would just silently change its behaviour (to something most likely not intended).

Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
  • "With the C-style cast I will not discover the mistake in time" - doesn't that hold only when casting between pointers? Can you give a non-pointer example of this claim? – barak manos Dec 17 '14 at 15:01
  • @barakmanos I meant this paragraph as "you're 1000% convinced that you're casting integers, but one of them is really a pointer." Edited to clarify. – Angew is no longer proud of SO Dec 17 '14 at 15:06
  • 1
    Or to put it another way, using `static_cast` helps you enforce this desirable constraint, that the source type is not a pointer. `int *ip = new int(); long j = static_cast(*ip);` is a stupid example, but writing it like that catches the error of typoing `ip` for `*ip`, whereas `long(*ip)` doesn't catch it because `long(ip)` is a valid C-style cast. – Steve Jessop Dec 18 '14 at 01:20
6

is static_cast used for non-pointer types only in order to maintain coding consistency?

No (well - yes, but not only).

It is also easy to find/replace. This is important in case of refactorings, bug fixing, etc.

It is a constraint on the cast type allowed: Consider an example where you have a C-style cast (which works fine) on a variable, then you change the declaration of the casted variable, to something which renders the cast invalid (for example, you change int x; to void * const x;).

The C-style cast suddenly performs another function (i.e. const_cast<...>(reinterpret_cast<...>(...)) with the same code.

If you write the initial code with a static_cast instead of a C-style cast, the compiler will let you know that static_cast in there is not actually performing a static cast.

utnapistim
  • 26,809
  • 3
  • 46
  • 82