C++ cast syntax styles - c++

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?

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.

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.

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.

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

I use static_cast for two reasons.
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.
It's easy to search for every place in my code where I'm casting.

The constructor syntax. C++ is OO, constructors exist, I use them.
If you feel the need to annotate these conversion ctor's you should do it for every type, not just the built-in ones. Maybe you use the 'explicit' keyword for conversion ctors but the client syntax mimics exactly what the ctor syntax for built-in types does.
Being greppable, that may be true, but what a big surprise that typing more characters makes searches easy. Why treat these ones as special?
If you are writing math formulas with lots of int/unsigned/... to and from double/float - graphics - and you need to write a static_cast every time, the look of the formula gets cluttered and is very much unreadable.
And it's an uphill battle anyway as a lot of times you will convert without even noticing that you are.
For downcasting pointers I do use the static_cast as of course no ctor exists by default that would do that.

C-style cast syntax, do not error check.
C++-style cast syntax, does some checking.
When using static_cast, even if it doesn't do checking, at least you know you should be carefull here.

C-style cast is the worst way to go. It's harder to see, ungreppable, conflates different actions that should not be conflated, and can't do everything that C++-style casts can do. They really should have removed C-style casts from the language.

We currently use C-style casts everywhere. I asked the other casting question, and I now see the advantage of using static_cast instead, if for no other reason than it's "greppable" (I like that term). I will probably start using that.
I don't like the C++ style; it looks too much like a function call.

Go for C++ style and, at worse, the ugly verbose code snippets that comprised C++'s explicit typecast will be a constant reminder of what we all know (i.e explicit casting is bad -- the lead to the coin-ing of expletives).
Do not go with C++ style if you want to master the art of tracking runtime errors.

Related

Why should I use 'static_cast' for numeric casts in C++?

Sometimes, we need to explicitly cast one numeric type to another (e.g. to avoid warning when we lose precision or range). For some:
double foo;
we could write:
(float)foo
but most C++ programmers say it's evil 'old-style cast' and you should use the 'new-style cast':
static_cast<float>(foo)
There is an alternative of boost::numeric_cast which is quite interesting (at least in not-performance-critical code) but this question is about static_cast.
A similar question was already asked, but the most important arguments used there are not valid for numerical cast (in my opinion, am I wrong?). There are they:
You have to explicitly tell the compiler what you want to do. Is it upcast, or downcast? Maybe reinterpret cast?
No. It is simple numeric cast. There is no ambiguity. If I know how static_cast<float> works, I know how does it work for 'old-style' cast.
When you write (T)foo you don't know what T is!
I'm not writting (T)foo but (float)foo. I know what is float.
Are there any important reasons for using a new, better casts for numeric types?
In a general scenario (which you have mentioned) you'd want explicit C++ cast to avoid possible issues mentioned in When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used? (ability to devolve into reinterpret_cast).
In numeric scenario you get two benefits at least:
you don't need to remember that C-style cast for numerics safely devolves to static_cast and never reaches reinterpret_cast - I'd call it "ease of use" and "no surprises" part
you can textually search for cast operations (grep 'static_cast<double>' vs grep '(double)' which can be part of function signature)
Like many things inherited from C, the more specific C++ variants are there to inform readers of the code, not the compiler.
You use static_cast<double> because it doesn't do all the things that (double) can.
The conversions performed by
a const_­cast,
a static_­cast,
a static_­cast followed by a const_­cast,
a reinterpret_­cast, or
a reinterpret_­cast followed by a const_­cast,
can be performed using the cast notation of explicit type conversion.
[expr.cast/4]
Specifying static_cast alerts you with a compile time error, rather than silently having undefined behaviour, if the expression you think is safe isn't.

What is the rationale for the C++ standard not allowing reinterpret_cast<int>( aFloatValue )?

Or equivalently
reinterpret_cast<int64>( aDoubleValue )
Allowing such a reinterpret_cast would not introduce any aliasing issues.
I understand that using memcpy to replicate bytes from a variable of one type into a variable of another type can achieve the necessary effect. And I understand that mature compilers with powerful optimizers can do wonderful things with such memcpy constructs.
That said I happen to be a compiler-writer. I am very aware of the many forms of optimization that must exist and the many preconditions that have to be met in order to pull off those dramatic optimizations. Do we really want to assume that every compiler is that powerful or that every programmer will write code successfully satisfying all of the necessary preconditions? Can we really fault programmers using non-mainstream compilers for being dubious that such a hoped-for optimization will occur?
The need to inspect the bits of a floating point values arises fairly often. Do we really want to insist that every programmer encountering such a need traffic in address-taken variables, char* exceptions to type aliasing rules, memcpy magic, etc?
The "new" (now pretty old) forms of casting provided in C++ are all basically subsets of things you can do with C-style casts ("basically" because they have a few minor additions like dealing with references, that just don't exist in C).
To get the equivalent of a reinterpret_cast with a C-style cast, you do something like:
int a = *(int *)&some_float;
So, with a reinterpret_cast, you do pretty much the same things, just changing the syntax for the cast itself with a reinterpret_cast instead:
int a = *reinterpret_cast<int *>&some_float;
As for defining what this does, so you can do it without violating any strict aliasing rules and such: I suspect the committee would probably be happy to consider a really well written proposal--I suspect the problem right now is that most think it would take a lot of work, and payoff would be minimal.
If the real intent is to support looking at the bits of a floating point number, it might be simpler to define something like a constructor for a bitset::bitset<float> or something on that order, to give a type that's already explicitly defined to give access to bits (though it would still probably be non-trivial to define how it's supposed to work in a way that's at all portable).
If all you want is a function that converts a float into its sequence of bits, memcpy can do that without running afoul of the strict aliasing rule:
unsigned int ConvertFloat(float f)
{
unsigned int ret;
std::memcpy(&ret, &f, sizeof(unsigned int));
return ret;
}
Live example.
You could even make a general template function for converting one type to another. One that would static_assert or SFINAE-check if the arguments are trivially-copyable.
In your line of work, converting floats to integers is a semi-frequent operation. But that's simply not true for most C++ users (or even most C users). So there is no widespread need for such a conversion operation.
Furthermore, the C++ standard doesn't require an implementation to provide any particular representation of a float. So even if the standard provided such a function, it couldn't tell you what it actually returned. There's not even guarantee that float can fit into an unsigned int.

What are the disadvantages of dynamic_cast in C++?

Despite the fact that dynamic_cast returns a 0 if the pointer that is being handled is of an incompatible type, why would you avoid using dynamic_cast?
It takes non-zero runtime. That is about it. C-casts and their c++ counter parts like: reinterpret or static are 0-overhead because they are performed during compilation.
Well for some, important part might be that they do need RTTI, which also introduces some overhead, for example to the code size, because compiler has to include type information into binary, which is not normally done. One should take note that this might be non-standard option in the compilers.
Also relevant note from wiki: "In the original C++ design, Bjarne Stroustrup did not include run-time type information, because he thought this mechanism was frequently misused."
EDIT: Following on the quote and the comments. I am not sure if this is really a drawback, I would like to point out, that when you use it, you should think if you really do need it.
Some just dislike it, some do misuse it.
Run-time overhead:
More memory is needed to store RTTI (see link).
Types must be checked at runtime.
Design Issues:
Types involved must be polymorphic.
Is often a sign of something else wrong in your code; why do you need to check?

What are the names of type(myVar) and (type)myVar? Are they both bad practice?

Almost a rehash of What's the difference between function(myVar) and (function)myVar?
But I want to know:
What is the name of these variants and are they 'bad'?
type(myVar) is constructor like syntax, but for a basic type is it the same as doing a C-style cast which is considered bad in C++?
(type)myVar this one certainly does seem to be a C-style cast and thus must be bad practice?
I've seen some instances where people replace things like (int)a with int(a) citing that the C-style version is bad/wrong yet the linked question says they're both the same!
What is the name of these variants
type(expr) is known as a function-style cast.
(type)(expr) is known as a C-style cast.
and are they 'bad'?
Yes. First off, both are semantically completely equivalent. They are “bad” because they aren’t safe – they might be equivalent to a static_cast, but equally a reinterpret_cast, and without knowing both type and the type of expr it’s impossible to say1. They also disregard access specifiers in some cases (C-style casts allow casting inside a private inheritance hierarchy). Furthermore, they are not as verbose as the explicit C++ style casts, which is a bad thing since casts are usually meant to stand out in C++.
1 Consider int(x): Depending on x’ type, this is either a static_cast (e.g. auto x = 4.2f;) or a reinterpret_cast (e.g. auto x = nullptr; on an architecture where int is large enough to hold a pointer).

Difference between static_cast<primitive_type>(foo) and primitive_type(foo) [duplicate]

I've heard that the static_cast function should be preferred to C-style or simple function-style casting. Is this true? Why?
The main reason is that classic C casts make no distinction between what we call static_cast<>(), reinterpret_cast<>(), const_cast<>(), and dynamic_cast<>(). These four things are completely different.
A static_cast<>() is usually safe. There is a valid conversion in the language, or an appropriate constructor that makes it possible. The only time it's a bit risky is when you cast down to an inherited class; you must make sure that the object is actually the descendant that you claim it is, by means external to the language (like a flag in the object). A dynamic_cast<>() is safe as long as the result is checked (pointer) or a possible exception is taken into account (reference).
A reinterpret_cast<>() (or a const_cast<>()) on the other hand is always dangerous. You tell the compiler: "trust me: I know this doesn't look like a foo (this looks as if it isn't mutable), but it is".
The first problem is that it's almost impossible to tell which one will occur in a C-style cast without looking at large and disperse pieces of code and knowing all the rules.
Let's assume these:
class CDerivedClass : public CMyBase {...};
class CMyOtherStuff {...} ;
CMyBase *pSomething; // filled somewhere
Now, these two are compiled the same way:
CDerivedClass *pMyObject;
pMyObject = static_cast<CDerivedClass*>(pSomething); // Safe; as long as we checked
pMyObject = (CDerivedClass*)(pSomething); // Same as static_cast<>
// Safe; as long as we checked
// but harder to read
However, let's see this almost identical code:
CMyOtherStuff *pOther;
pOther = static_cast<CMyOtherStuff*>(pSomething); // Compiler error: Can't convert
pOther = (CMyOtherStuff*)(pSomething); // No compiler error.
// Same as reinterpret_cast<>
// and it's wrong!!!
As you can see, there is no easy way to distinguish between the two situations without knowing a lot about all the classes involved.
The second problem is that the C-style casts are too hard to locate. In complex expressions it can be very hard to see C-style casts. It is virtually impossible to write an automated tool that needs to locate C-style casts (for example a search tool) without a full blown C++ compiler front-end. On the other hand, it's easy to search for "static_cast<" or "reinterpret_cast<".
pOther = reinterpret_cast<CMyOtherStuff*>(pSomething);
// No compiler error.
// but the presence of a reinterpret_cast<> is
// like a Siren with Red Flashing Lights in your code.
// The mere typing of it should cause you to feel VERY uncomfortable.
That means that, not only are C-style casts more dangerous, but it's a lot harder to find them all to make sure that they are correct.
One pragmatic tip: you can search easily for the static_cast keyword in your source code if you plan to tidy up the project.
In short:
static_cast<>() gives you a compile time checking ability, C-Style
cast doesn't.
static_cast<>() can be spotted easily
anywhere inside a C++ source code; in contrast, C_Style cast is harder to spot.
Intentions are conveyed much better using C++ casts.
More Explanation:
The static cast performs conversions between compatible types. It
is similar to the C-style cast, but is more restrictive. For example,
the C-style cast would allow an integer pointer to point to a char.
char c = 10; // 1 byte
int *p = (int*)&c; // 4 bytes
Since this results in a 4-byte pointer pointing to 1 byte of allocated
memory, writing to this pointer will either cause a run-time error or
will overwrite some adjacent memory.
*p = 5; // run-time error: stack corruption
In contrast to the C-style cast, the static cast will allow the
compiler to check that the pointer and pointee data types are
compatible, which allows the programmer to catch this incorrect
pointer assignment during compilation.
int *q = static_cast<int*>(&c); // compile-time error
Read more on:
What is the difference between static_cast<> and C style casting
and
Regular cast vs. static_cast vs. dynamic_cast
The question is bigger than just using whether static_cast<> or C-style casting because there are different things that happen when using C-style casts. The C++ casting operators are intended to make those different operations more explicit.
On the surface static_cast<> and C-style casts appear to be the same thing, for example when casting one value to another:
int i;
double d = (double)i; //C-style cast
double d2 = static_cast<double>( i ); //C++ cast
Both of those cast the integer value to a double. However when working with pointers things get more complicated. Some examples:
class A {};
class B : public A {};
A* a = new B;
B* b = (B*)a; //(1) what is this supposed to do?
char* c = (char*)new int( 5 ); //(2) that weird?
char* c1 = static_cast<char*>( new int( 5 ) ); //(3) compile time error
In this example (1) may be OK because the object pointed to by A is really an instance of B. But what if you don't know at that point in code what a actually points to?
(2) may be perfectly legal (you only want to look at one byte of the integer), but it could also be a mistake in which case an error would be nice, like (3).
The C++ casting operators are intended to expose these issues in the code by providing compile-time or run-time errors when possible.
So, for strict "value casting" you can use static_cast<>. If you want run-time polymorphic casting of pointers use dynamic_cast<>. If you really want to forget about types, you can use reintrepret_cast<>. And to just throw const out the window there is const_cast<>.
They just make the code more explicit so that it looks like you know what you were doing.
static_cast means that you can't accidentally const_cast or reinterpret_cast, which is a good thing.
Allows casts to be found easily in
your code using grep or similar
tools.
Makes it explicit what kind
of cast you are doing, and engaging
the compiler's help in enforcing it.
If you only want to cast away
const-ness, then you can use
const_cast, which will not allow you
to do other types of conversions.
Casts are inherently ugly -- you as
a programmer are overruling how the
compiler would ordinarily treat your
code. You are saying to the
compiler, "I know better than you."
That being the case, it makes sense
that performing a cast should be a
moderately painful thing to do, and
that they should stick out in your
code, since they are a likely source
of problems.
See Effective C++ Introduction
It's about how much type-safety you want to impose.
When you write (bar) foo (which is equivalent to reinterpret_cast<bar> foo if you haven't provided a type conversion operator) you are telling the compiler to ignore type safety, and just do as it's told.
When you write static_cast<bar> foo you are asking the compiler to at least check that the type conversion makes sense and, for integral types, to insert some conversion code.
EDIT 2014-02-26
I wrote this answer more than 5 years ago, and I got it wrong. (See comments.) But it still gets upvotes!
C Style casts are easy to miss in a block of code. C++ style casts are not only better practice; they offer a much greater degree of flexibility.
reinterpret_cast allows integral to pointer type conversions, however can be unsafe if misused.
static_cast offers good conversion for numeric types e.g. from as enums to ints or ints to floats or any data types you are confident of type. It does not perform any run time checks.
dynamic_cast on the other hand will perform these checks flagging any ambiguous assignments or conversions. It only works on pointers and references and incurs an overhead.
There are a couple of others but these are the main ones you will come across.
static_cast, aside from manipulating pointers to classes, can also be used to perform conversions explicitly defined in classes, as well as to perform standard conversions between fundamental types:
double d = 3.14159265;
int i = static_cast<int>(d);