Yes this is not very portable, I wonder why one would want to do something like this:`
char *cp ;
reinterpret_cast<char *&>(a) = cp;
` and what it means?
Thx
Yes this is not very portable, I wonder why one would want to do something like this:`
char *cp ;
reinterpret_cast<char *&>(a) = cp;
` and what it means?
Thx
a
is casted to a char*&
. It is called reinterpret_cast
because the bits are reinterpreted in exactly the fashion requested by the cast target type. The compiler does not check for validity (nor would he be able to). This brings a pointer back to its origins: it's just an address of a piece of memory.
The reason a
is casted to a reference to a pointer is that a reference is needed to have a valid lvalue to assign cp
to. reinterpret_cast<char *>(a) = cp
would have been illegal because you can't assign to a temporary.
It looks a bit ugly in source code. This one:
char* c = reinterpret_cast<char*>(a);
c = cp;
is probably better to maintain and read, although it's longer (note it's not exactly the same meaning because we're introducing an extra variable c
to hold the result of the cast. In the original sample, a
's memory is reused to point to the new location cp
).
Some people are confused about the reference in the cast. Without the reference, we would have something like this:
T a; // whatever a is, we don't know
char* cp; // or something convertible to char*
// remember, this is not what actually gets generated
char* some_temporary_rvalue = reinterpret_cast<char*>(a);
some_temporary_rvalue = cp; // illegal, and senseless
With the reference, it becomes:
T a; // whatever a is, we don't know
char* cp; // or something convertible to char*
char*& a_treated_as_charptr = reinterpret_cast<char*&>(a);
a_treated_as_charptr = cp; // assigns a char* that is at &a
The interesting part, missing from the question is the type of a
. I can just assume that it is some kind of pointer (it can actually be anything, but that assumption makes the discussion simpler).
T *a;
char* p = "Hello";
reinterpret_cast<char*&>(a) = p;
Under the assumption that a
is in fact a pointer to another type, the result of the operation would be equivalent to:
T *a;
char *p = "Hello";
a = reinterpret_cast<T*>(p); // convert p to a T* and assign
The difference being that in the first version, the cast is being performed in the left hand side (LHS) of the assignment and thus must be a cast to a reference (lvalue), while in the second case the cast is performed in the right hand side (RHS) and thus a rvalue suffices and there is no need to cast to a reference.
Now, in the general case there are differences in the two casts. Reinterpret cast will just 'reinterpret' the memory as the type you tell it to. If the type of a
and char*
are of the same size (which under the assumption above holds, all pointers have the same size), then the two operations are the same and yield the same result.
On the other hand, if one type is bigger than the other then the two operations are not equivalent. If sizeof(a) > sizeof(char*)
the first version will reinterpret the variable and overwrite only the first sizeof(char*)
bytes of a
with the value of p
. In the second case it will read sizeof(a)
bytes from the memory location of p
(causing undefined behavior, as it will read beyond the variable) and copy those bytes overwritting all the previous bytes in a
.
The opposite goes if sizeof(a) < sizeof(char*)
then the first version will overwrite beyond the allocated space for a
causing undefined behavior, while the second will overwrite a
with the first sizeof(a)
bytes in p
.