最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

c++ - Is reinterpret_cast between unrelated types allowed if they are standard layout in C++20 - Stack Overflow

matteradmin5PV0评论

There have already been many questions on casts, but since C++20 there are a few additional constructs that relate to type casts and hence this question. Consider the following class structure.

struct A {
  int index;
}

struct B: A {}

static_assert(std::is_standard_layout_v<A>, "test");
static_assert(std::is_standard_layout_v<B>, "test");

Both types are standard-layout, which we can verify via a static_assert. For these according to the standard following holds:

Two objects a and b are pointer-interconvertible if:

  • one is a standard-layout class object and the other is the first non-static data member of that object, or, if the object has no non-static data members, any base class subobject of that object (11.4), or

Meaning that the following code should be allowed:

A a = {};
int* i = reinterpret_cast<int*>(&a);
B* b = reinterpret_cast<B*>(i);

However, my question is if it is actually allowed to use b for anything. In particular, it seems to me that type aliasing rules forbid accessing (or writing) lvalue b per the following statement.

If a program attempts to read or modify the stored value of an object through a lvalue(until C++11)glvalue(since C++11) through which it is not type-accessible, the behavior is undefined.

The rules for type-accessible are not entirely clear to me after reading the description it seems that the dynamic type of b is A. Since this relates to typed based aliasing rules, so a follow up question would be if -fno-strict-aliasing would allow such conversions.

If people are wondering about the context. It is from a legacy code base where A has some accessors and B (and many other derived types) are essentially different views on this underlying object, and it is sometimes necessary to convert between these types (and in the actual implementation this is expensive). At the time people though that since alignment and size are the same, that such casts would be sound and cheaper than explicit constructions. However, in general, this does not seem to be case. Unfortunately I could not find any compiler flag or sanitizer that actually shows that this is UB, or was able to construct an example where this goes wrong.

Post a comment

comment list (0)

  1. No comments so far