Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
260 views
in Technique[技术] by (71.8m points)

c++ - Why Doesn't reinterpret_cast Force copy_n for Casts between Same-Sized Types?

According to cppreference.com, reinterpret_cast:

Converts between types by reinterpreting the underlying bit pattern.

But wait, that's a lie cause it only works in these cases:

When a pointer or reference to object of type T1 is reinterpret_cast (or C-style cast) to a pointer or reference to object of a different type T2, the cast always succeeds, but the resulting pointer or reference may only be accessed if both T1 and T2 are standard-layout types and one of the following is true:

  • T2 is the (possibly cv-qualified) dynamic type of the object
  • T2 and T1 are both (possibly multi-level, possibly cv-qualified at each level) pointers to the same type T3
  • T2 is the (possibly cv-qualified) signed or unsigned variant of the dynamic type of the object
  • T2 is an aggregate type or a union type which holds one of the aforementioned types as an element or non-static member (including, recursively, elements of subaggregates and non-static data members of the contained unions): this makes it safe to cast from the first member of a struct and from an element of a union to the struct/union that contains it.
  • T2 is a (possibly cv-qualified) base class of the dynamic type of the object
  • T2 is char or unsigned char

According to that list an illegal example would be:

auto foo = 13LL;
auto bar = reinterpret_cast<double&>(foo);

So the only acceptable way to make that cast is to copy the memory:

auto foo = 13LL;
double bar;

copy_n(reinterpret_cast<char*>(&foo), sizeof(foo), reinterpret_cast<char*>(&bar));

My question is, why doesn't reinterpret_cast handle that for me? Or is there something else available so I don't have to jump through this hoop?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

why doesn't reinterpret_cast handle that for me?

One reason is that the size, alignment, and bit representations aren't specified, so such a conversion wouldn't be portable. However, that wouldn't really justify making the behaviour undefined, just implementation-defined.

By making it undefined, the compiler is allowed to assume that expressions of unrelated types don't access the same object, which can allow better optimisation. For example, in the following:

int   & i = something();
float & f = something_else();

const int i1 = i;
f = 42;
const int i2 = i;

the compiler can assume that i1 and i2 both have the same value (i being unchanged by the assignment to f), and optimise them into a single constant. Breaking the assumption will then cause undefined behaviour.

Or is there something else available so I don't have to jump through this hoop?

Copying the bytes is the only well-defined way to reinterpret one object type as an unrelated type.

Aliasing with reinterpret_cast or a union might work sometimes (assuming the size etc. match), but might trip you up if the optimiser gets too clever with undefined behaviour.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...