C++ cast syntax styles

16,607

Solution 1

It's best practice never to use C-style casts for three main reasons:

  • as already mentioned, no checking is performed here. The programmer simply cannot know which of the various casts is used which weakens strong typing
  • the new casts are intentionally visually striking. Since casts often reveal a weakness in the code, it's argued that making casts visible in the code is a good thing.
  • this is especially true if searching for casts with an automated tool. Finding C-style casts reliably is nearly impossible.

As palm3D noted:

I find C++-style cast syntax too verbose.

This is intentional, for the reasons given above.

The constructor syntax (official name: function-style cast) is semantically the same as the C-style cast and should be avoided as well (except for variable initializations on declaration), for the same reasons. It is debatable whether this should be true even for types that define custom constructors but in Effective C++, Meyers argues that even in those cases you should refrain from using them. To illustrate:

void f(auto_ptr<int> x);

f(static_cast<auto_ptr<int> >(new int(5))); // GOOD
f(auto_ptr<int>(new int(5));                // BAD

The static_cast here will actually call the auto_ptr constructor.

Solution 2

According to Stroustrup:

The "new-style casts" were introduced to give programmers a chance to state their intentions more clearly and for the compiler to catch more errors.

So really, its for safety as it does extra compile-time checking.

Solution 3

Regarding this subject, I'm following the recommandations made by Scott Meyers (More Effective C++, Item 2 : Prefer C++-style casts).

I agree that C++ style cast are verbose, but that's what I like about them : they are very easy to spot, and they make the code easier to read (which is more important than writing).

They also force you to think about what kind of cast you need, and to chose the right one, reducing the risk of mistakes. They will also help you detecting errors at compile time instead at runtime.

Solution 4

I use static_cast for two reasons.

  1. It's explicitly clear what's taking place. I can't read over that without realizing there's a cast going on. With C-style casts you eye can pass right over it without pause.
  2. It's easy to search for every place in my code where I'm casting.

Solution 5

Definitely C++-style. The extra typing will help prevent you from casting when you shouldn't :-)

Share:
16,607
palm3D
Author by

palm3D

Computer scientist

Updated on June 12, 2022

Comments

  • palm3D
    palm3D almost 2 years

    A question related to Regular cast vs. static_cast vs. dynamic_cast:

    What cast syntax style do you prefer in C++?

    • C-style cast syntax: (int)foo
    • C++-style cast syntax: static_cast<int>(foo)
    • constructor syntax: int(foo)

    They may not translate to exactly the same instructions (do they?) but their effect should be the same (right?).

    If you're just casting between the built-in numeric types, I find C++-style cast syntax too verbose. As a former Java coder I tend to use C-style cast syntax instead, but my local C++ guru insists on using constructor syntax.

    What do you think?

  • Jason
    Jason about 14 years
    looking like a function call can be nice, it allows you to have utility functions which share the same style such as the common lexical_cast for converting from strings <-> numeric types. But that's just an opinion.
  • Blindy
    Blindy over 13 years
    I wonder how many times have you searched for a cast in your code with an automated tool...
  • Konrad Rudolph
    Konrad Rudolph over 13 years
    @Blindly: it happens. I have already done that. Remember that in C++, unlike some other languages (Java, C#), you can usually program without casts. Every explicit cast in your code is a potential design flaw. Identifying casts in your C++ code is an important step in refactoring. In C# it would of course be ridiculous to search for casts in code – they’re everywhere!
  • Puppy
    Puppy almost 12 years
    @Konrad: And, of course, both Java and C# also have their own dynamic_cast equivalent which is a special cast.
  • Johannes Schaub - litb
    Johannes Schaub - litb over 11 years
    "which of the various casts is used". that's a simple one. it always uses a c style cast. no need trying to translate it to a c++ style cast
  • user666412
    user666412 over 10 years
    in the auto_ptr example, isn't the "bad" call constructing a temp auto_ptr, rather than attempting to cast the pointer?
  • Konrad Rudolph
    Konrad Rudolph over 10 years
    @user666412 I think you misunderstand what a cast does: it also creates a temporary auto_ptr. A cast is nothing special in this regard, only the syntax changes.
  • augustin
    augustin over 8 years
    There are two problems with your answer: 1) you mention "two main reasons" but you list three. :) +1
  • Ruslan
    Ruslan over 8 years
    Isn't the // GOOD actually nonsense here? It'd be quite awful to write something like static_cast<std::string>("hello") instead of std::string("hello") or any similar construction of object of user type.
  • Konrad Rudolph
    Konrad Rudolph over 8 years
    @Ruslan Well several C++ authorities disagree with you.
  • underscore_d
    underscore_d almost 7 years
    static_cast always checks that the source and destination types are compatible. (It can't protect users against their mistake if they convert a base to a derived type that it doesn't really have, but that's their fault.)
  • underscore_d
    underscore_d over 5 years
    Then someone should have no problem citing precisely where and with what wording (a) Sutter and (b) the rest of the "several C++ authorities" said anything of the sort, because it sounds like (i) news and (ii) nonsense to me.
  • Konrad Rudolph
    Konrad Rudolph over 5 years
    @underscore_d I did cite one of these authorities in my answer. For what it’s worth the style certainly hasn’t caught on, and is also somewhat obsolete with uniform initialisation.
  • underscore_d
    underscore_d over 5 years
    That's a relief! What I was hoping was that the section where Sutter said that was excerpted somewhere so that I could read his reasoning, but I'm guessing not? (at least not all these years/editions later) That or another actual, specific citation. But yeah, it doesn't matter if it's rightly superseded.
  • callyalater
    callyalater over 5 years
    One very good reason to avoid functional style casts is the most vexing parse. Consider this: int a = 42; MyDoubleClass d(double(a)); What is d? Answer: A function called d that takes a double as a parameter and returns an object of type MyDoubleClass.