Why use static_cast<int>(x) instead of (int)x?

static_cast vs dynamic_cast
static_cast vs (int)
static_cast nullptr
static_cast enum
static_cast<size_t>
static_cast reference
static_cast template
static_cast<char>

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.

Why use static_cast<int>(x) instead of (int)x , static_cast is the first cast you should attempt to use. It does things like implicit conversions between types (such as int to float , or pointer to void* ), and it can  Static Cast: This is the simplest type of cast which can be used. It is a compile time cast .It does things like implicit conversions between types (such as int to float, or pointer to void*), and it can also call explicit conversion functions (or implicit ones).

One pragmatic tip: you can search easily for the static_cast keyword in your source code if you plan to tidy up the project.

When should static_cast, dynamic_cast, const_cast and , Static Cast: This is the simplest type of cast which can be used. It is a compile time cast.It does things like implicit conversions between types (such as int to float,  The static_cast operator can be used for operations such as converting a pointer to a base class to a pointer to a derived class. Such conversions are not always safe. In general you use static_cast when you want to convert numeric data types such as enums to ints or ints to floats, and you are certain of the data types involved in the conversion.

In short:

  1. static_cast<>() gives you a compile time checking ability, C-Style cast doesn't.
  2. static_cast<>() can be spotted easily anywhere inside a C++ source code; in contrast, C_Style cast is harder to spot.
  3. 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

static_cast in C++, operations such as: converting a pointer of a base class to a pointer of a non-virtual derived class; converting numeric data types such as enums to ints or ints to floats. In C++ the static_cast<>() will allow the compiler to check whether the pointer and the data are of same type or not. If not it will raise incorrect pointer assignment exception during compilation. char c = 65; //1-byte data.

The question is bigger than just using wither 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 these operations more explicit.

On the surface static_cast and C style casts appear to 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 these 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) maybe 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) maybe 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, : This cast is used for handling polymorphism. You only need to use it when you're casting to a derived class. The static_cast operator converts variable j to type float. This allows the compiler to generate a division with an answer of type float . All static_cast operators resolve at compile time and do not remove any const or volatile modifiers.

static_cast means that you can't accidentally const_cast or reinterpret_cast, which is a good thing.

static_cast in C++, The (int)x is C style typecasting where static_cast (x) is used in C++. This static_cast<>() gives compile time checking facility, but the C style  static_cast: This is used for the normal/ordinary type conversion. This is also the cast responsible for implicit type coersion and can also be called explicitly. You should use it in cases like converting float to int, char to int, etc. This can cast related type classes.

Regular cast vs. static_cast vs. dynamic_cast in C++, This type of static_cast is used to implement move semantics in std::move. (since C++11). 4) If new_type is the type void  Noted that when static_cast<>-ing CDerived* to CBaseY* (line 5), the result is CDerived* offset by 4. To know what static_cast<> is actually doing, we have to take a look at the memory layout of CDerived. Memory Layout of CDerived. As shown in the diagram, CDerived's memory layout contains two objects, CBaseX and CBaseY, and the compiler knows

How to explain the differences among static_cast, reinterpret_cast , The static_cast<> operator can be used for operations such as: converting a pointer of a base class to a pointer of a non-virtual derived class;; converting  This type of static_cast is used to implement move semantics in std::move. (since C++11) 4) If new_type is the type void (possibly cv-qualified), static_cast discards the value of expression after evaluating it.

Why use static_cast<int>(x) instead of (int)x in C++?, static_cast can be used to convert between pointers to related classes (up or down the inheritance hierarchy). It can also perform implicit  Downcasting with static_cast. It turns out that downcasting can also be done with static_cast. The main difference is that static_cast does no runtime type checking to ensure that what you’re doing makes sense. This makes using static_cast faster, but more dangerous.

Comments
  • Objection your honour, asked and answered.
  • I disagree, this other question was about describing the differences between casts introduces in C++. This question is about the real usefulness of static_cast, which is slightly different.
  • We could certainly merge the two questions, but what we'd need to preserve from this thread is the advantage of using functions over C-style casting, which is currently only mentioned in a one-line answer in the other thread, with no votes.
  • This question is about "built-in" types, like int, whereas that question is about class types. That seems like a significant enough difference to merit a separate explanation.
  • static_cast is actually an operator, not a function.
  • You shouldn't use static_cast for casting down an inheritance hierarchy, but rather dynamic_cast. That will return either the null pointer or a valid pointer.
  • @David Thornley: I agree, usually. I think I indicated the caveats to using static_cast in that situation. dynamic_cast might be safer, but it's not always the best option. Sometimes you do know that a pointer points to a given subtype, by means opaque to the compiler, and a static_cast is faster. In at least some environments, dynamic_cast requires optional compiler support and runtime cost (enabling RTTI), and you might not want to enable it just for a couple of checks you can do yourself. C++'s RTTI is only one possible solution to the problem.
  • Your claim about C casts is false. All C casts are value conversions, roughly comparable to C++ static_cast. The C equivalent of reinterpret_cast is *(destination_type *)&, i.e. taking the address of the object, casting that address to a pointer to a different type, and then dereferencing. Except in the case of character types or certain struct types for which C defines the behavior of this construct, it generally results in undefined behavior in C.
  • Your fine answer addresses the body of the post. I was looking for an answer to the title "why use static_cast<int>(x) instead of (int)x". That is, for type int (and int alone), why use static_cast<int> vs. (int) as the only benefit seems to be with class variables and pointers. Request that you elaborate on this.
  • @chux, for int dynamic_cast doesn't apply, but all the other reasons stand. For example: let's say v is a function parameter declared as float, then (int)v is static_cast<int>(v). But if you change the parameter to float*, (int)v quietly becomes reinterpret_cast<int>(v) while static_cast<int>(v) is illegal and correctly caught by the compiler.
  • you can search using the brackets also though such as "(int)" but good answer and valid reason to use C++ style casting.
  • @Mike that will find false positives - a function declaration with a single int parameter.
  • This can give false negatives: if you're searching a codebase where you're not the only author, you won't find C-style casts others might have introduced for some reasons.