-1

So far I understand that static_cast is a compile time action that somehow analyzes the memory of the entity and tries to convert it to the specified object.

I see static_cast used extensively as static_cast<T *>. What's the reason for this? Is it because the compiler needs a pointer to check the memory layout of the object?

example:

union U { int a; double b; } u;
void* x = &u;                        // x's value is "pointer to u"
double* y = static_cast<double*>(x); // y's value is "pointer to u.b"
char* z = static_cast<char*>(x);     // z's value is "pointer to u"

For static_cast<T> this fails however:

double yy = static_cast<double>(u); error: cannot convert 'union U' to 'double' without a conversion operator

I spoted this type of casting first in the use of classes and looks like it is more used there.

Derived * d = new Derived();
Base * b = static_cast<Base *>(d);

However the same question remains:

Base b1 = Base();
Derived d2 = Derived();

b1 = static_cast<Base>(d2);
// No error here

Can I please receive a detail explanation of how static_cast works behind the scenes and how it relates to memory (thus objects) and (if neccessary) the instructions that take place?

VladiC4T
  • 216
  • 2
  • 10
  • No, `static_cast` does not "analyze the memory" of anything. As far as what that asterisk means there, that means a pointer. A full and complete discussion of pointers in C++ is found ine very C++ textbook. This is where you find the "detail explanation" you're looking for. Once you go through that, the reason for this kind of a cast, here, should be easier to understand. Otherwise, this is just too broad of a question for Stackoverflow. – Sam Varshavchik Mar 03 '21 at 18:35
  • Does this answer your question? [C++ polymorphism without pointers](https://stackoverflow.com/questions/7223613/c-polymorphism-without-pointers) – Ruzihm Mar 03 '21 at 18:38
  • 1
    Striving to understand what goes "behind the scenes" before learning the specification is going about it backwards. You won't understand *why* a compiler does something unless you first learn what behavior it's trying to produce. – StoryTeller - Unslander Monica Mar 03 '21 at 18:39
  • How it should not? If I understood correctly it is the same that a compiler does with implicit conversions (like I said). With respect to my question I think you are failing to realize that pointers and "static_cast" are two completely different things, from a beginner's perspective. – VladiC4T Mar 03 '21 at 18:39
  • Basically, 1. Polymorphism is the typical purpose for using static_cast, 2. Polymorphism in practical terms always uses pointers to the polymorphic classes – Ruzihm Mar 03 '21 at 18:44

2 Answers2

4

It might be helpful to consider two different use cases for static_cast: one for converting non-pointer types to one another, and one for converting pointer types to one another.

When converting non-pointer types to one another, static_cast has the meaning of "do the kind of conversion that you would do if you initialized an object of the target type from the source value." So, for example, in this code:

int aASCII = 64;
cout << static_cast<char>(aASCII) << endl; // Prints 'A'

the static_cast<char>(aASCII) means "give me the char value I would get here if I were to initialize a new char value to aASCII." It's analogous to doing the following:

int aASCII = 64;
char temp = aASCII;
cout << temp << endl;

Similarly, consider this code:

int total = 137;
int numItems = 42;
cout << static_cast<double>(total) / numItems << endl;

the static_cast<double>(total) bit means "pretend that total is a double here when doing the division." It's analogous to writing

int total = 137;
int numItems = 42;
double temp = total;
cout << temp / numItems << endl;

With that in mind, why doesn't this code compile?

double yy = static_cast<double>(u); // Oops!

The reason why is that this is kinda sorta is like writing

double temp = u; // Oops, doesn't compile
double yy = temp;

Here, this won't compile because you can't initialize a double to a variable of union type U.

The use of static_cast with pointers uses a different set of rules. When working with pointers, static_cast means "please pretend the pointer points at an object of the type I want it to point at, but only if there's some plausible universe in which that could work." So, for example, this is perfectly legal:

Base* ptr = new Derived;
Derived* dPtr = static_cast<Derived*>(ptr);

Here, this says "I have a pointer of type Base*. There is a plausible world in which it really points to a Derived. Please convert the pointer to a Derived*, but don't do any runtime checks to make sure this is safe. I'm aware that if this doesn't actually point at a Derived, then Bad Things will happen."

You couldn't, however, write this:

float* ptr = new float[137];
Derived* dPtr = static_cast<Derived*>(ptr); // Error!

This won't work because there's no way for a pointer of type float* to point at a Derived object (without doing something really horrible to some pointer at some point in time).

The reason that your code

double* y = static_cast<double*>(x); // y's value is "pointer to u.b"

is fine is because x is a void*, which can point at any (non-function) entity, so it's plausible that it could point at a double.

Dharman
  • 30,962
  • 25
  • 85
  • 135
templatetypedef
  • 362,284
  • 104
  • 897
  • 1,065
  • are the following operations considered the same? `void* x = &u; double* d = reinterpret_cast(&u);` same as? `double* w = static_cast(x);` …(note reinterpret and static) – VladiC4T Mar 04 '21 at 12:35
0

What's the difference between static_cast<type> and static_type<type *>?

type and type* are different types. First cast converts to one type and second cast converts to the other type.

I see static_cast used extensively as static_cast<T *>. What's the reason for this?

Because probably in those cases the intention is to convert to the type T*.

eerorika
  • 232,697
  • 12
  • 197
  • 326