Why do you need a C-style cast for the following?
int* ptr = static_cast<int*>(0xff); // error: invalid static_cast from type 'int'
// to type 'int*'
int* ptr = (int*) 0xff; // ok.
static_cast can only cast between two related types. An integer is not related to a pointer and vice versa, so you need to use reinterpret_cast instead, which tells the compiler to reinterpret the bits of the integer as if they were a pointer (and vice versa):
int* ptr = reinterpret_cast<int*>(0xff);
Read the following for more details:
Type conversions
You need a C-style cast or directly the reinterpret_cast it stands for when casting an integer to a pointer, because the standard says so for unrelated types.
The standard mandates those casts there, because
you are doing something dangerous there.
you are doing something very seldom useful.
you are doing something highly implementation-dependent.
most times, that is simply a programming-error.
When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used?
Regular cast vs. static_cast vs. dynamic_cast
Being late to the party I found that the following works only using static casts:
int* ptr1 = static_cast<int*>(static_cast<void*>(static_cast<unsigned char*>(nullptr) + 0xff));
This way you don't translate the constant directly to a pointer, instead you add it as a bytewise offset to the nullptr.
Related
I ran into this problem while trying to traverse a byte array where the data length in bytes is known at run-time.
https://godbolt.org/z/-vgEk_
#include <cstdint>
void f()
{
uint8_t* array = new uint8_t[4*10];
// cannot convert 'unsigned char*' to 'unsigned int*' in initialization
uint32_t* fourByteIterator1 = array;
// invalid static_cast from 'unsigned char*' to 'unsigned int*'
uint32_t* fourByteIterator2 = static_cast<uint32_t*>(array);
// no problems
uint32_t* fourByteIterator3 = (uint32_t*)array;
// no problems
void* intermediate = static_cast<void*>(array);
uint32_t* fourByteIterator4 = static_cast<uint32_t*>(p);
// no problems
uint32_t* fourByteIterator5 = reinterpret_cast<uint32_t*>(array);
}
Why does static_cast fail in the second conversion? And then, why is it valid to cast from void* to uint32_t* if that is not valid when directly casting to uint32_t* using static_cast? Is statically casting a pointer type twice via void* the same as a direct reinterpret cast?
uint32_t* fourByteIterator1 = (whatever_cast)array;
Accessing fourByteIterator1 is Undefined Behavior, no matter how you manage to get the cast working. Accessing the memory obtained from new uint8_t[4*10]; as objects of type uint32_t is a violation of the strict aliasing rules.
As for why some methods of casts work and other don't ... well... that's what the standard says. And the rules are like they are to protect you from making mistakes. The fact that you cannot directly cast between them except with reinterprect_cast is a very good indication that you probably shouldn't.
The cast via void* works because any pointer type can be casted to void * and if you cast back to the original pointer type you are guaranteed to get the original pointer back. So that's why casting to and from void * is "more allowed" then other pointer types. But that's not what you are doing. You are not casting back to the original pointer type.
Is statically casting a pointer type twice via void* the same as a
direct reinterpret cast?
Yes.
In conclusion: don't do that. It is Undefined Behavior.
I know that reinterpret_cast is primarily used going to or from a char*.
But I was surprised to find that static_cast could do the same with a void*. For example:
auto foo "hello world"s;
auto temp = static_cast<void*>(&foo);
auto bar = static_cast<string*>(temp);
What do we gain from using reinterpret_cast and char* over static_cast and void*? Is it something to do with the strict aliasing problem?
Generally speaking, static_cast will do cast any two types if one of them can be cast to the other implicitly. That includes arithmetic casts, down-casts, up-casts and cast to and from void*.
That is, if this cast is valid:
void foo(A a);
B b;
foo(b);
Then the both static_cast<B>(a) and static_cast<A>(b) will also be valid.
Since any pointer can be cast implicitly to void*, thus your peculiar behavior.
reinterpret_cast do cast by reinterpreting the bit-pattern of the values. That, as you said in the question, is usually done to convert between unrelated pointer types.
Yes, you can convert between unrelated pointer types through void*, by using two static_cast:
B *b;
A *a1 = static_cast<A*>(b); //compiler error
A *a2 = static_cast<A*>(static_cast<void*>(b)); //it works (evil laugh)!
But that is bending the rules. Just use reinterpret_cast if you really need this.
Your question really has 2 parts:
Should I use static_cast or reinterpret_cast to work with a pointer to the underlying bit pattern of an object without concern for the object type?
If I should use reinterpret_cast is a void* or a char* preferable to address this underlying bit pattern?
static_cast: Converts between types using a combination of implicit and user-defined conversions
In 5.2.9[expr.static.cast]13 the standard, in fact, gives the example:
T* p1 = new T;
const T* p2 = static_cast<const T*>(static_cast<void*>(p1));
It leverages the implicit cast:
A prvalue pointer to any (optionally cv-qualified) object type T can be converted to a prvalue pointer to (identically cv-qualified) void. The resulting pointer represents the same location in memory as the original pointer value. If the original pointer is a null pointer value, the result is a null pointer value of the destination type.*
There is however no implicit cast from a pointer of type T to a char*. So the only way to accomplish that cast is with a reinterpret_cast.
reinterpret_cast: Converts between types by reinterpreting the underlying bit pattern
So in answer to part 1 of your question when you cast to a void* or a char* you are looking to work with the underlying bit pattern, reinterpret_cast should be used because it's use denotes to the reader a conversion to/from the underlying bit pattern.
Next let's compare void* to char*. The decision between these two may be a bit more application dependent. If you are going to use a standard library function with your underlying bit pattern just use the type that function accepts:
void* is used in the mem functions provided in the cstring library
read and write use char* as inputs
It's notable that C++ specific libraries prefer char* for pointing to memory.
Holding onto memory as a void* seems to have been preserved for compatibility reasons as pointer out here. So if a cstring library function won't be used on your underlying bit patern, use the C++ specific libraries behavior to answer part 2 of your question: Prefer char* to void*.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
When should static_cast, dynamic_cast and reinterpret_cast be used?
I'm using c function in c++, where a structure passed as a void type argument in c is directly stored that same structure type.
eg in C.
void getdata(void *data){
Testitem *ti=data;//Testitem is of struct type.
}
to do the same in c++ i use static_cast:
void foo::getdata(void *data){
Testitem *ti = static_cast<Testitem*>(data);
}
and when i use reinterpret_cast it does the same job, casting the struct
when i use Testitem *it=(Testitem *)data;
this does the same thing too.
But how is the structure gets affected by using the three of them.
A static_cast is a cast from one type to another that (intuitively) is a cast that could under some circumstance succeed and be meaningful in the absence of a dangerous cast. For example, you can static_cast a void* to an int*, since the void* might actually point at an int*, or an int to a char, since such a conversion is meaningful. However, you cannot static_cast an int* to a double*, since this conversion only makes sense if the int* has somehow been mangled to point at a double*.
A reinterpret_cast is a cast that represents an unsafe conversion that might reinterpret the bits of one value as the bits of another value. For example, casting an int* to a double* is legal with a reinterpret_cast, though the result is unspecified. Similarly, casting an int to a void* is perfectly legal with reinterpret_cast, though it's unsafe.
Neither static_cast nor reinterpret_cast can remove const from something. You cannot cast a const int* to an int* using either of these casts. For this, you would use a const_cast.
A C-style cast of the form (T) is defined as trying to do a static_cast if possible, falling back on a reinterpret_cast if that doesn't work. It also will apply a const_cast if it absolutely must.
In general, you should always prefer static_cast for casting that should be safe. If you accidentally try doing a cast that isn't well-defined, then the compiler will report an error. Only use reinterpret_cast if what you're doing really is changing the interpretation of some bits in the machine, and only use a C-style cast if you're willing to risk doing a reinterpret_cast. In your case, you should use the static_cast, since the downcast from the void* is well-defined in some circumstances.
I want to reinterpret an unsigned long (actually, a DWORD) as a signed long. I tried:
DWORD x;
long y = reinterpret_cast<signed long>(x);
However, VC++2010 intellisense tells me "Invalid type conversion". Why? How do I fix it?
You don't need reinterpret_cast to convert unsigned type into a signed one, static_cast will do.
try static_cast instead. VC generates an error if you try an excessively permissive cast (like using reinterpret_cast when static_cast or const_cast will suffice).
There are 5 types of casts in C++, each of which allows you to do more (grants more permissions). The least permissive casts are const casts (const_cast<int>(<const int>)) which allow you to change the const modifier. There are static casts (static_cast<int>)(<short>)) which allow you to perform type safe coersions (cast base to derived, for example).There are dynamic casts (dynamic_cast<derived_type>(base_type) that allow you to cast from one type to another if there is a legal conversion between the two (and that return null if there is no conversion). Finally, there are casts that allow conversion between unrelated types - reinterpret_cast reinterpret_cast<int>(<void *>) and C style cast (int)<void *>.
I don't have a good way of describing these different types of casts, so I describe them as "more permissive" because each of them allows you to do more.
VC warns you if you are using a reinterpret cast when one of the other cast types would be more appropriate to achieve your goal. C style casts don't have a similar warning for backwards compatibility.
int i = 1000;
void *p = &i;
int *x = static_cast<int*>(p);
int *y = reinterpret_cast<int*>(p);
which cast should be used to convert from void* to int* and why?
static_cast provided that you know (by design of your program) that the thing pointed to really is an int.
static_cast is designed to reverse any implicit conversion. You converted to void* implicitly, therefore you can (and should) convert back with static_cast if you know that you really are just reversing an earlier conversion.
With that assumption, nothing is being reinterpreted - void is an incomplete type, meaning that it has no values, so at no point are you interpreting either a stored int value "as void" or a stored "void value" as int. void* is just an ugly way of saying, "I don't know the type, but I'm going to pass the pointer on to someone else who does".
reinterpret_cast if you've omitted details that mean you might actually be reading memory using a type other than the type is was written with, and be aware that your code will have limited portability.
By the way, there are not very many good reasons for using a void* pointer in this way in C++. C-style callback interfaces can often be replaced with either a template function (for anything that resembles the standard function qsort) or a virtual interface (for anything that resembles a registered listener). If your C++ code is using some C API then of course you don't have much choice.
In current C++, you can't use reinterpret_cast like in that code. For a conversion of void* to int* you can only use static_cast (or the equivalent C-style cast).
For a conversion between different function type pointers or between different object type pointers you need to use reinterpret_cast.
In C++0x, reinterpret_cast<int*>(p) will be equivalent to static_cast<int*>(p). It's probably incorporated in one of the next WPs.
It's a misconception that reinterpret_cast<T*>(p) would interpret the bits of p as if they were representing a T*. In that case it will read the value of p using p's type, and that value is then converted to a T*. An actual type-pun that directly reads the bits of p using the representation of type T* only happens when you cast to a reference type, as in reinterpret_cast<T*&>(p).
As far as I know, all current compilers allow to reinterpret_cast from void* and behave equivalent to the corresponding static_cast, even though it is not allowed in current C++03. The amount of code broken when it's rejected will be no fun, so there is no motivation for them to forbid it.
When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used? gives some good details.
From the semantics of your problem, I'd go with reinterpret, because that's what you actually do.