3 ms·
Author here. :) I'm not saying that T's object representation needs to be known to the programmer, or portable, or unique, or anything concrete like that. This
by quuxplusone 3y ago
Author here. :) I'm not saying that T's object representation needs to be known to the programmer, or portable, or unique, or anything concrete like that. This is about a relationship between the foo operation on T itself and the foo operation on T's object representation.
For example, we say that T is trivially copy-constructible iff T's copy constructor is defined such that making a copy of a T object is tantamount to making a copy of T's object representation (i.e., a memcpy). Given these two functions...
struct ObjRep { alignas(T) char data_[sizeof(T)]; };
void copy_value(T *s, T *d) { ::new (d) T(*s); }
void copy_repr(ObjRep *s, ObjRep *d) { ::new (d) ObjRep(*s); }
...if T is trivially copy-constructible, then these functions can (and in practice will) generate exactly the same code.
Certain types are guaranteed by the Standard to be trivially fooable for certain foos (e.g. `int` is guaranteed to be trivially copyable, and so is `std::string_view` since C++23). Vice versa, it's often physically obvious when a type can't be trivially fooable; e.g. `std::string_view` can't possibly be trivially equality comparable. For most types, the Standard makes no guarantee, so different vendors may do different things... but each individual vendor must do some thing! And for most of these foos, we can just query a type-trait to find out what the compiler has done in the case of any given T.
Here's a godbolt where you can just fill in some data members and user-provided special member functions for `T`, and see the codegen for yourself. https://godbolt.org/z/97d3o3vbW https://godbolt.org/z/97d3o3vbW
You mentioned padding bytes. Padding prevents trivial comparability, but does not affect any other trivial fooability that I can think of off the top of my head.