Consider the following code. I can be compiled with both Clang
and GCC
. However, GCC
issues a warning warning: ‘void* memcpy(void*, const void*, size_t)’ writing to an object of non-trivially copyable type ‘struct Value’; use copy-assignment or copy-initialization instead [-Wclass-memaccess]
.
#include <cstring>
#include <iostream>
#include <type_traits>
static unsigned cnt2 = 0;
struct Value {
Value(int v) noexcept : v(v), m(v+1) { }
~Value() noexcept { cnt2++; }
int v;
int m;
};
static_assert(std::is_trivially_copy_assignable_v<Value>);
void copy(Value* dst, Value const* src, std::size_t len) {
std::memcpy(dst,src,sizeof(Value)*len); }
int main() { std::cout << "Hello\n"; }
There are at least two problems here.
- Both compilers pass
std::is_trivially_copy_assignable_v<Value>
. So what is the difference between trivially copy assignable and trivially copyable types? - I think the warning is correct. Because destructor of
Value
is non-trivial. So does this mean that to usestd::memcpy
we have to check bothstd::is_trivially_copy_assignable_v<Value>
andstd::is_trivially_destructible_v<Value>
?
Aucun commentaire:
Enregistrer un commentaire