Closed
Description
Consider the following example:
#include <type_traits>
#include <cstddef>
class A1 {
private:
int i;
char ch;
};
class B1 {
public:
[[no_unique_address]] A1 a;
char ch;
};
static_assert(std::is_standard_layout_v<B1>);
class A2 {
public:
int i;
char ch;
};
class B2 {
public:
[[no_unique_address]] A2 b2;
char ch;
};
static_assert(std::is_standard_layout_v<B1>);
static_assert(offsetof(B1, ch) != offsetof(B2, ch));
Godbolt: https://godbolt.org/z/1o91bE
Following the standard wording A1
and A2
are layout compatible [1]. Similarly B1
and B2
are layout compatible. However the ch
member in B1
has different offset than the ch
member in B2
.
A1
is not POD for the purpose of layout while A2
is, this affects the offset of the ch
member.
Two possible directions to fix this:
- Modify the standard to disallow
[[no_unique_address]]
non-empty non-static data members to be part of a common initial sequence (or maybe only allow as the last element of a common initial sequence). - Modify the ABI to disable overlapping of
[[no_unique_address]]
non-empty data members in standard-layout classes.
Personally I would prefer the first option of these two.
Metadata
Metadata
Assignees
Labels
No labels