admin管理员组

文章数量:1399965

Suppose I have the following two classes

class a {
    int m1;
    float m2;
    char m3[8];
};

class b {
    int n1;
    float n2;
    char n3[8];
};

Can I use std::memcpy to copy an object of type a into an object of type b like this:

a my_a; // Imagine we assigned to the members of my_a.
b my_b;
std::memcpy(&my_b, &my_a, sizeof(a));

and then get the correct values from the members of my_b?

If yes, how does this work in the general case, would the set of trivially copyable types be the largest set in which we can use std::memcpy on different types as long as they have identical members in identical order?

Also, is the following condition enough to check if the operation is valid?

std::is_layout_compatible_v<T, U> && std::is_trivially_copyable_v<T> && std::is_trivially_copyable_v<U>) == true

Suppose I have the following two classes

class a {
    int m1;
    float m2;
    char m3[8];
};

class b {
    int n1;
    float n2;
    char n3[8];
};

Can I use std::memcpy to copy an object of type a into an object of type b like this:

a my_a; // Imagine we assigned to the members of my_a.
b my_b;
std::memcpy(&my_b, &my_a, sizeof(a));

and then get the correct values from the members of my_b?

If yes, how does this work in the general case, would the set of trivially copyable types be the largest set in which we can use std::memcpy on different types as long as they have identical members in identical order?

Also, is the following condition enough to check if the operation is valid?

std::is_layout_compatible_v<T, U> && std::is_trivially_copyable_v<T> && std::is_trivially_copyable_v<U>) == true
Share Improve this question asked Mar 24 at 16:05 sayurcsayurc 6524 silver badges11 bronze badges 4
  • 1 Can the person who voted to close the question explain why the question is not focused enough? Yes, there are three question marks in the text, but all these questions are tightly related and aren’t useful without the others. What’s the point of asking if I can use std::memcpy without also asking about which types I can use it with, and without asking how to check for these types? – sayurc Commented Mar 24 at 16:30
  • You're already got the "trivally copyable" check, the other one of interest is "common initial sequence of members" (which is intended in the context of unions but directly addresses the memory layout) – Ben Voigt Commented Mar 24 at 16:31
  • I would use static_assert with std::bit_cast to ensure that the two structures are identical. example:static_assert(0x00030201==std::bit_cast<DWORD>(RGBQUAD{1,2,3}) – 許恩嘉 Commented Mar 24 at 16:37
  • 1 @許恩嘉 a more useful example would be something like: static_assert(offsetof(a,m1)==offsetof(b,n1) && offsetof(a,m2)==offsetof(b,n2) && offsetof(a,m3)==offsetof(b,n3)) but depending on implementation it might not work for private members. – Remy Lebeau Commented Mar 24 at 19:23
Add a comment  | 

1 Answer 1

Reset to default 1

Having identical members is not enough. They also need to have identical alignment and padding requirements to ensure that all of the members are located at identical byte offsets relative to their containing object.

本文标签: