C++26 will introduce std::is_trivially_relocatable_v
, and the proposal author states: Trivially copyable implies trivially relocatable.
However, I think the statement might not always be true, especially in case that a pointer member points to another member of the same object.
Consider the following code:
struct A {
int n{};
int* pn{};
};
static_assert(std::is_trivially_copyable_v<A>); // true
int main() {
auto a = A{};
a.n = 1;
a.pn = &a.n;
auto b = A{};
std::memcpy(&b, &a, sizeof(a));
// Now, b.pn points to a.n, rather than b.n.
// So, A should not be regarded as trivially relocatable.
}
My question is:
Does trivially copyable imply trivially relocatable?
Does trivially copyable imply trivially relocatable?
Yes.
If you rely on pn
not dangling, your code exhibits bugs if A
is copied. The same bugs occur if A
is relocated.
struct A {
int n{};
int* pn{};
};
static_assert(std::is_trivially_copyable_v<A>); // true
int main() {
auto a = A{};
a.n = 1;
a.pn = &a.n;
auto b = A{};
std::memcpy(&b, &a, sizeof(a));
// Now, b.pn points to a.n, rather than b.n.
// IF THIS IS BAD, A should not be trivially relocatable.
auto c = a;
// Now, c.pn points to a.n, rather than c.n.
// IF THIS IS BAD, A should not be trivially copyable.
}
If you consider it wrong for pn
to dangle, there is a bug in your code.
This bug does not make relocation less correct than copying.