Home c++ are static_cast and (int) the same thing?

are static_cast and (int) the same thing?

Author

Date

Category

I can’t understand why static_cast , if you can do the same using direct type casting.


Answer 1, authority 100%

This is a very hackneyed topic. Why do you need it? well, because they have a little different behavior. There is a very good article here that describes the difference.

Here is a quote with an answer to the question

What the C-style cast does: tries to use static_cast , if it fails, uses reinterpret_cast . Further uses const_cast if needed.

One more argument – any static_cast is easier to find with a search.

Two more links to threads where this is actively discussed – habr and rsdn.org .


Answer 2, authority 89%

The problem is that () casting can mean a million different things that you don’t even know about, depending on the context.

First, it performs arithmetic type conversions. If you want int from double , it calculates the integer part. If you want char from long , it strips off significant digits.

Second, it strips off the const and volatile specifiers. Unbeknownst to you.

Third, it converts int to and from a pointer.

Fourth, it transforms pointers up and down the inheritance hierarchy.

Fifth, it converts pointers as reinterpret_cast based on bit representation.

In contrast, static_cast does only conversion of arithmetic types (for arithmetic types) and conversion of pointers up and down the inheritance hierarchy (for pointers). [You can still cast completely “unfamiliar” types to each other in two steps, via void * , but this already needs to be done explicitly and cannot be done by mistake. Here is complete list of rules .]

In many cases, you don’t need the insane power of () ghosting, because it can hide errors. Examples:

void f (char * str);
void g (const _TCHAR * txt)
{
  f ((char *) txt); // compiles
  f (static_cast & lt; char * & gt; (txt)); // does not compile
}

The call here most likely shouldn’t compile because the f function expects a single-byte string and is probably not ready to work with wchar_t * . If the f function can work with such strings, you can use reinterpret_cast . For the case of () -casting, you have no way of distinguishing between these cases.

void f (char * str);
void g (const char * txt)
{
  f ((char *) txt); // compiles
  f (static_cast & lt; char * & gt; (txt)); // does not compile
}

Here again, the call should not compile, because the f function has the right to modify the string, and the characters in txt cannot be modified.

Of course, in such simple examples, the problem is visible to the “naked eye”. But if the function g is a template, and the exact type of txt is not known at the point of the function definition, it is much more difficult for you to catch such errors. In this case, static_cast will allow you to catch them even at the compilation stage, without causing the program to crash.


Answer 3, authority 39%

An expression of the form (T) is described in chapter 5.4 Explicit type conversion (cast notation) [expr.cast] .

It tries the following transforms in turn

  • const_cast
  • static_cast
  • static_cast and then const_cast
  • reinterpret_cast
  • reinterpret_cast and then const_cast

This removes the restriction on the visibility of the base class for conversions between pointers / references to descendant classes and base classes for static_cast . (And also when converting between pointers to class members).

class Base {};
class Derived: private Base {};
Derived * d = new Derived ();
// static_cast & lt; Base * & gt; (d); // will not compile: Base is not available (private)
Base * b = (Base *) d; // OK
// static_cast & lt; Derived * & gt; (b); // will not compile: Base is not available (private)
Derived * d2 = (Derived *) b; // OK

If several conversions are possible at the same time, then the code will not compile. (For example, in the case of multiple inheritance, there may be two base classes with the same type)

You can convert incomplete class types. At the same time, the standard does not indicate which cast will be made, static_cast or reinterpret_cast .

struct X;
struct Y;
X * blind_cast (Y * y) {
  // return static_cast & lt; X * & gt; (y); // won't compile: incomplete types
  return (X *) y; // OK
}

If we define these types

struct Base1 {int some; };
struct X {};
struct Y: Base1, X {};

That expression static_cast & lt; X * & gt; (y) == blind_cast (y) can be either true or false :

  • if at the time of code generation the compiler sees the complete type definitions, then it will static_cast ,
  • if blind_cast is compiled separately, then the compiler will not see the full type definitions and will reinterpret_cast , then the result of blind_cast will actually point to Base1 , and the comparison will return false .

Programmers, Start Your Engines!

Why spend time searching for the correct question and then entering your answer when you can find it in a second? That's what CompuTicket is all about! Here you'll find thousands of questions and answers from hundreds of computer languages.

Recent questions