tags:

views:

722

answers:

8

After reading here a lot of answers about C-style casting in C++ I still have one little question. Can I use C-style casting for built-in types like long x=(long)y; or it's still considered bad and dangerous?

+20  A: 

Can I use C-style casting for built-in types like long x=(long)y; or it's still considered bad and dangerous?

Don't use them, ever. The reasons against using them applies here as well. Basically, once you use them, all bets are off because the compiler won't help you any more. While this is more dangerous for pointers than for other types, it's potentially still dangerous and gives poor compiler diagnostics in the case of errors, whereas new style casts offer richer error messages since their usage is more constrained: Meyers cites the example of casting away constness: using any cast other than const_cast won't compile, thus making it clear what happens here.

Also, some other disadvantages apply regardless of the types, namely syntactic considerations: A C-style cast is very unobtrusive. This isn't good: C++ casts stand out clearly in the code and point to potentially dangerous code. They can also easily be searched for in IDEs and text editors. Try searching for a C-style cast in a large code and you'll see how hard this is.

On the other hand, C-style casts offer no advantages over C++ casts so there's not even a trade-off to consider.

More generally, Scott Meyers advises to “Minimize casts” in Effective C++ (item 27), because “casts subvert the type system.”

Konrad Rudolph
True about minimizing casts. But seriously can you point out any reason not to do float y = 1.0; double x = double(y)? Because *that* wsa the question. This cast is not dangerous and probably should _not_ distract compared to the real dangerous ones (which you almost never need if you do it right)..
ypnos
Well, in that very specific case, the cast is not even needed as double is a larger type than float.
RaphaelSP
A: 

Meyers told me not to do that. so I don't

Jace Jung
+1  A: 

If you find you need to do a C-style cast (or a reinterpret_cast) then look very carefully at your code it is 99.99% certain there is something wrong with it. Both these casts leed almost inevitably to implementation specific (and very often undefined) behaviour.

anon
"If you lie to the compiler, it will punish you". These casts are either a lie, or an attempt to fix a previous lie.
Darron
In research code I see often dealing with float and double side by side, or e.g. int data from an image getting casted to float/double for further processing. These are real use cases for a cast and I think they are more than 0.01%.
ypnos
What about parameters to thread functions on Windows? You have to pass void*. Common pattern is to pass reinterpret_cast<void*>(this).
Dave Mooney
+8  A: 

I would not, for the following reasons:

  • Casts are ugly and should be ugly and stand out in your code, and be findable using grep and similar tools.
  • "Always use C++ casts" is a simple rule that is much more likely to be remembered and followed than, "Use C++ casts on user-defined types, but it's OK to use C-style casts on built-in types."
  • C++ style casts provide more information to other developers about why the cast is neccesary.
  • C-style casts may let you do conversions you didn't intend -- if you have an interface that takes in (int*) and you were using c-style casts to pass it a const int*, and the interface changes to take in a long*, your code using c-style casts will continue to work, even if it's not what you wanted.
JohnMcG
A: 

Why do you need that particular cast? Any numeric type can be converted to a long without a cast (at potential loss of precision), so casting doesn't let the compiler do anything it can't already. By casting, all you do is remove the compiler's ability to warn if there is a potential problem. If you're converting some other basic type (like a pointer), to a long, I'd really like to see a reinterpret_cast<> rather than a C-type cast, so I can find what's going on easily if there turns out to be a problem.

I'm not going to approve of casting without a reason, and I'm certainly not going to approve of C-type casts without a good reason. I don't see a reason to cast between most built-in types, and if there is one I want to be able to find it easily with a text search.

David Thornley
If you don't want the compiler to generate loss-of-precision errors then casting is necessary
Michael
Sure, but you may be better off suppressing them for now. When we went to 64-bit processing (needed more memory space), we would have lost precision in some cases (involving size_t) if we'd been casting.
David Thornley
+1  A: 

I think it may be OK given the context. Example:

/* Convert -1..1 to -32768..32767 */
short float_to_short(float f)
{
    return (short)(max(-32768.f, min(32767.f, f * 32767.f)));
}
kotlinski
+1  A: 

I can think of one legitimate use for a C-style cast:
// cast away return value to shut up pedandic compiler warnings
(void)printf("foo\n");

tragomaskhalos
A: 

In my opinion C-Style casting of built in types when using standard library functions and STL is ok, and results in easier to read code.

In the company I work in we compile with maximum (level 4) warnings, so we get warnings about every little type cast etc... So I use c-style casts in these because they're small, not so verbose and make sense.

for (int i = 0; i < (int)myvec.size(); i++)
{
  // do something int-related with i
}
float val = (float)atof(input_string);

etc....

But if its on (eg library) code that may change, then static_cast<>() is better because you can ensure the compiler will error out if types change and the cast no longer makes sense. Also, its impossible to search for casts within code if you only use c-style. "static_cast<mytype>(" is pretty easy to search for. :)