Re: What would you think about this method of string copy?
On Nov 19, 7:05 pm, Joshua Maurice <joshuamaur...@gmail.com> wrote:
It doesn't matter if you
cast through a char*. What matters is how you access the object. Ex:
#include <iostream>
int main()
{
int* x = new int;
//fine, though potentially dangerous
char* c = reinterpret_cast<char*>(x);
//fine because of the char exception in 3.10 / 15
std::cout << *c;
/*not UB (undefined behavior) yet (?), but it is nonsensical
because the result cannot be used in any meaningful way.
At the very least, it is implementation dependent because short
may have a different alignment requirement than char.
*/
short* s = reinterpret_cast<short*>(c);
/*UB, accessing an object through an lvalue of the wrong type
*/
std::cout << *s;
}
Actually technically, according to what I just wrote, I'm wrong. I
realized just after I hit submit.
std::cout << *s;
is still is undefined behavior. Actually, so is
std::cout << *c;
for the same reason. Both read uninitialized memory, so UB. Let's take
this example instead:
#include <iostream>
int main()
{
int* x = new int(1);
//fine, though potentially dangerous
char* c = reinterpret_cast<char*>(x);
//fine because of the char exception in 3.10 / 15
std::cout << *c;
/*not UB (undefined behavior) yet (?), but it is nonsensical
because the result cannot be used in any meaningful way.
At the very least, it is implementation dependent because short
may have a different alignment requirement than char.
*/
short* s = reinterpret_cast<short*>(c);
/*UB, accessing an object through an lvalue of the wrong type
*/
std::cout << *s;
}
Moreover, let's also consider this example, with descriptions correct
as far as I can tell from reading the standard, and as to its intent
and how the compiler writers interpret it:
int main()
{
int * x = new int;
//fine, but probably stupid,
short * s = reinterpret_cast<short*>(x);
//
/* As far as I can tell from reading the standard, this is
actually fine. We have a piece of storage, so we can create a new POD
object in that storage by writing to that storage through an lvalue of
that POD type.
*/
*s = 1;
//
/* UB (undefined behavior).
An int object does not exist at that storage - a short object
does, so you're reading an object through an lvalue of the wrong
type.
Instead, if we wrote to the storage through an int lvalue instead
of reading from the storage, then we would have reused the storage and
created a new int object, and we would not have undefined behavior.
*/
return *x;
}