Date: Tue, 13 Oct 2020 19:09:49 +0100
Hi all,
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.
In the Itanium ABI 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.
I also submitted an issue here:
https://github.com/itanium-cxx-abi/cxx-abi/issues/108
[1] https://eel.is/c++draft/class#mem.general-22
Regards,
Lénárd Szolnoki
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.
In the Itanium ABI 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.
I also submitted an issue here:
https://github.com/itanium-cxx-abi/cxx-abi/issues/108
[1] https://eel.is/c++draft/class#mem.general-22
Regards,
Lénárd Szolnoki
Received on 2020-10-13 13:09:57