Ferenc Deak
Ferenc Deak

Reputation: 35398

About static_cast in c++

I am reading http://www.gotw.ca/gotw/036.htm (it is about direct initialization and copy initialization) and it has a mention like:

static_cast<S>(t); // performing a static_cast

A static_cast uses direct initialization.

Can someone explain why and how does static_cast need to use initialization? I thought that casting is just reinterpreting the bits in a given memory location...

Upvotes: 3

Views: 1141

Answers (4)

Mike Seymour
Mike Seymour

Reputation: 254421

I thought that casting is just reinterpreting the bits in a given memory location...

No, casting performs a type conversion. In this case, it converts t to type S; such a conversion is possible since T inherits from S, so a new S can be made by copying that part of t. Copying a base sub-object like that is sometimes known as slicing.

Can someone explain why and how does static_cast need to use initialization?

A type conversion requires the creation of a (temporary) object of the new type; that object needs to be initialised and the rules for static_cast specify that it use direct initialisation. Since S is a class type, this means it's initialised by calling a suitable constructor - in this case, the implicitly-declared copy constructor, which initialises the object by copying the S sub-object of t.

Upvotes: 0

Nikos Athanasiou
Nikos Athanasiou

Reputation: 31489

Maybe this is not an fully explanatory example, but watch the following

void f(double **arg) {} // just to make a point

int main() {
    double d(1.);
    double *pd = &d;
    double const *cpd = &d;

    f(&pd); // OK 
    f(&(const_cast<double*>(cpd))); // Error
}

The emmited error is

error C2102: & requires l-value

The static_cast would behave the same way, in the sense that they return an r-value which you must bind to a variable. It is that variable that gets initialized

Upvotes: 0

MichaelCMS
MichaelCMS

Reputation: 4763

static_cast is performing look up in the class hierarchy in order to cast to the correct class, it doesn't reinterpret the bits (that is reinterpret_cast).

The same thing happens with dynamic_cast, the difference being that static_cast is done at compile time while dynamic_cast is done at runtime.

Take the following example : A : B , A : C , D : B,C

The following code will print that the pointers point to a different memory block

{
  D *ptrToD = new D();
  C *ptr1 = static_cast<C>(ptrToD);
  C *ptr2 = reinterpret_cast<C>(ptrToD);
  if (ptr1==ptr2)
  {
     printf("Pointers point to the same memory block");
  } else
  {
     printf("Pointers point to different memory blocks");
  }
}

If you look at the memory , it will look something like ABACD

If you want to cast it to C , C starts from where D starts +sizeof(B) (AC) ,whereas A and B starts from the same memory block as D.

Upvotes: 0

Sebastian Redl
Sebastian Redl

Reputation: 71899

A reinterpret_cast reinterprets the bits. A static_cast is a semantics-aware conversion. It will try to find a sensible operation that converts a value from one type to another, and fail to compile if it can't.

Sensible operations are conversion (possibly with truncation) between various integer and floating point types, automatic conversions to bool, converting bool to numbers, etc. And also, using user-defined conversion operators and single-argument constructors to convert from and to user-defined types. And in the case where it uses constructors, it uses direct-initialization, and thus can use explicit constructors, unlike implicit conversion, which cannot.

Upvotes: 5

Related Questions