Is it possible to completely exclude C-style in C ++?

I don’t believe that when writing C ++, you can completely avoid the C-style cast. I was surprised to learn that I needed to use the C-style to avoid the warning about compiler truncation:

short value_a = 0xF00D; // Truncation warning in VS2008 short value_b = static_cast<short>(0xF00D); // Truncation warning in VS2008 short value_c = (short)0xF00D; // No warning! 

Are there any other scenarios in which there is no C ++ style C-style replacement?

+6
c ++ c casting
source share
6 answers

You're just trying to confuse your code, it's that simple. And the compiler is completely right in telling you this.

If you have a clear idea of ​​the meaning of a value, use this. I assume that you have some unreasonable presumption of short with a width of 16 bits and that representing the sign of the target machine is two additions. If so, assign -4083 to your variable. If you just need your variable as a bit vector, use an unsigned type.

As for C, the standard just talks about converting from one integer type to another:

Otherwise, the new type will be signed and the value cannot be represented in it; either the result is a specific implementation or the signal determined by the implementation is raised.

I believe that C ++'s point of view with this respect is not much different. Other answers mention border cases in which in C ++ you will need a “C'-style” to undo all the typechecks that C ++ gives you. The sense of need is an indicator of poor design.

The case that you cite as an example, of course, is not the one for which I will find any valid circumstances.

+2
source share

In C ++, C-style casting is defined (§5.4) in terms of C ++ style. Thus, for each cast you can make a C-style, there is a corresponding C ++ - style (almost).

“Almost” is that a C-style cast ignores the accessibility of the base class. That is, the C ++ equivalent is not applicable for the following actions:

 struct foo {}; struct bar : private foo {}; bar b; foo* f = (foo*)&b; // only way this can be done in a well-defined manner 

So no, it’s not strictly speaking to completely discard the C-style. But the number of areas in which there are not enough (in combination) C ++ styles is not enough.


The above "language answer". What you experience has nothing to do with C-style castes and C ++ castes, but just a compiler implementation. Warnings are absolutely implementation specific and have nothing to do with C ++.

So do not make mistakes when using your data in this particular compiler in this particular situation in order to conclude about C ++ in general.

+10
source share

Yes, it is quite possible.

I never use C-style casts. I can write hundreds of thousands of lines of code without reverting to using reinterpret_cast , C ++ closes my cousin for a C-style cast. The only time I have to use reinterpret_cast is when socket programming is pretty narrow domain in the big picture.

You also do not need to use C-style. In your other post you said

I could just use a negative value,

 short my_value = -4083; 

but in my code it is much clearer to use hex.

So, in this case you did not need to use a throw. You choosed.

+2
source share

I was surprised to learn that I need to use C-style to avoid the warning about compiler truncation

I see it the other way around: you use the C-style for warning the compiler from , and I consider this a serious drawback of the C-style cast.

if you feel that you know what you are doing, then close the compiler for this case using the compiler method. For example, for VC use something like

 #pragma warning(push, disable: XXXX) // code goes here #pragma warning(pop) 
0
source share

There are 4 C ++ styles, const_cast, reinterpret_cast, static_cast and dynamic_cast. They work as follows:

 // const_cast casts away constness or adds it const int const_integer = 5; const_cast<int>(const_integer) = 3; // static_cast will perform standards defined casts and will // cast up or down a c++ inheritance hierarchy without checking the result of the cast struct b {}; struct a : public b {}; struct c {}; double value = static_cast<double>(0.0f); b* b_value = new b; a* a_value = static_cast<a*>(b_value); // dynamic_cast will perform any cast that static_cast will, but will check to see // if the cast makes sense. If the values are not pointers, this cast can throw b* value_b = new b; a* value_a = new a; b* new_b = dynamic_cast<b*>(value_a); // will return NULL a* new_a = dynamic_cast<a*>(value_b); // will not return NULL // reinterpret_cast will change any type to any other type, as long as the constness of the types is the same. // the behavior of this cast is implementation specific. double* a = new double; *a = 0.0f; int *b = reinterpret_cast<int*>(a); 

A c-style cast in C ++ simply tries to execute these casts in a specific order until one of them works. This order is as follows:

  • a const_cast
  • static_cast
  • static_cast followed by const_cast
  • reinterpret_cast or
  • reinterpret_cast followed by const_cast.

So, in a word, you can make any c-style in C ++, because c-style cast in C ++ is just some kind of layout of C ++ style applications. Get it?

0
source share

In these cases, you can use reinterpret_cast . It was intended to replace the uncontrolled C-style accompaniment. A typical note here: this is an untested cast, and should be avoided when possible using the other available ones: const_cast , dynamic_cast , etc.

-3
source share

All Articles