Kieran Chandler
Kieran Chandler

Reputation: 188

C++ Why do we need to explicitly cast from one type to another?

I was writing some code recently and found myself doing a lot of c-style casts, such as the following:

Client* client = (Client*)GetWindowLong(hWnd, GWL_USERDATA);

I thought to myself; why do we actually need to do these?

I can somewhat understand why this would be needed in circumstances where there is lot of code where the compiler may not what types can be converted to what, such as when using reflection.

but when casting from a long to a pointer where both types are of the same size, I don't understand why the compiler would not allow us to do this?

Upvotes: 2

Views: 111

Answers (2)

Galik
Galik

Reputation: 48605

I think the idea is that we want compiler to tell us when we are doing something dodgy and/or potentially unintended. That way we don't do it by accident. So the compiler complains unless we explicitly tell the compiler that this is what we really, really want. We do that by using the a cast.

Edited to add:

It might be better to ask why we are allowed to cast between types. Originally C was created as a strongly typed language. Although it allows promotion/conversion between related object types (like between ints and floats) it is supposed to prevent access and assignment to the wrong type as a language feature, a safety measure. However occasionally this is useful so casting was put in the language to allow us to circumvent the type rules on those occasions when we need to.

Upvotes: 4

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726479

when casting from a long to a pointer where both types are of the same size, I don't understand why the compiler would not allow us to do this?

Ironically, this is the place where compiler's intervention is most important!

In vast majority of situations, converting between long and a pointer is a programming error which you don't want to go unnoticed, even if your platform allows it.

For example, when you write this

unsigned long *ptr = getLongPtr();
unsigned long val = ptr; // Probably an error

it is almost a certainty that you are missing an asterisk in front of ptr:

unsigned long val = *ptr; // This is what it should be

Finding errors like this without compiler's help is very hard, hence the compiler wants you to tell it that you know when you are doing on conversions like that.

Moreover, something that is fine on one platform may not work on other platforms. For example, an integral type and a pointer may have the same size on 32-bit platforms, but have different sizes on 64-bit platform. If you want to maintain any degree of portability, the compiler should warn you of the conversion even on the 32-bit platform, where the sizes are identical. Compiler warning will help you identify an error, and switch to a portable pointer-as-integer type intptr_t.

Upvotes: 6

Related Questions