6.8 Types

1
【注:[[𝑏𝑎𝑠𝑖𝑐.𝑡𝑦𝑝𝑒𝑠]]()及其子条款对类型的表示向实现提出了要求。类型分为两种:基本类型和复合类型。类型用于描述对象、引用或函数。——注释结束】
2
对于任意一个平凡可复制类型T的对象(除了潜在重叠的子对象之外),无论该对象是否持有类型T的有效值,构成该对象的底层字节([[𝑖𝑛𝑡𝑟𝑜.𝑚𝑒𝑚𝑜𝑟𝑦]]())都可以被复制到一个`char`、`unsigned char`或`std::byte`([[𝑐𝑠𝑡𝑑𝑑𝑒𝑓.𝑠𝑦𝑛]]())数组中。如果将该数组的内容再复制回该对象中,那么该对象随后应当持有其原始值。【示例:
1
2
3
4
5
constexpr std::size_t N = sizeof(T);
char buf[N];
T obj; // obj initialized to its original value
std::memcpy(buf, &obj, N); // between these two calls to std​::​memcpy, obj might be modified
std::memcpy(&obj, buf, N); // at this point, each subobject of obj of scalar type holds its original value
——示例结束】
3
对于任意一个平凡可复制类型T,如果有两个指向T的指针分别指向不同的T对象`obj1`和`obj2`,且`obj1`与`obj2`都不是潜在重叠的子对象,那么如果将构成`obj1`的底层字节([[𝑖𝑛𝑡𝑟𝑜.𝑚𝑒𝑚𝑜𝑟𝑦]]())复制到`obj2`中,`obj2`随后应当持有与`obj1`相同的值。【示例:
1
2
3
4
5
6
T* t1p;
T* t2p;
// provided that t2p points to an initialized object ...
std::memcpy(t1p, t2p, sizeof(T));
// at this point, every subobject of trivially copyable type in *t1p contains
// the same value as the corresponding subobject in *t2p
——示例结束】
4
类型T的一个对象的对象表示(`object representation`)是由该T类型对象所占用的N个`unsigned char`对象组成的序列,其中`N`等于`sizeof(T)`。类型T的一个对象的值表示(`value representation`)是用于表示类型T值的那一组比特。对于在对象表示中而不在值表示中的比特是填充比特(`padding bits`)。对于平凡可复制类型,其值表示是对象表示中的一组比特,这组比特决定了一个值,而该值是由实现定义的值集合中的一个离散元素。
Paw5zx个人理解:点击查看更多

对象表示:整个存储空间的原始二进制数据,标准规定可以视其为sizeof(T)unsigned char组成的数组。
值表示:对象表示中真正用来编码数值信息的比特
填充比特:没用来表示数值的那些比特,可能只是占位或对齐

例如:
在某平台,bool占1字节,但只用最低1位来表示truefalse,所以bit1-7都是填充比特

6.8.1 Fundamental types

6.8.2 Compound types

4
两个对象`a`和`b`是指针可互换(`pointer-interconvertible`)的,当且仅当:
(4.1)
- 它们是同一个对象,或者
(4.2)
- 它们一个是联合体对象,另一个是该对象([[class.union]]())的一个非静态数据成员,或者
(4.3)
- 它们一个是标准布局类对象,另一个是该对象的第一个非静态数据成员;或者,如果该对象没有非静态数据成员,则另一个是该对象的任意基类子对象([[class.mem]]()),或者
(4.4)
- 存在某个对象`c`,使得`a`与`c`指针可互换,且`c`与`b`指针可互换。
如果两个对象是指针可互换的,那么它们具有相同的地址,并且可以通过reinterpret_cast将其中一个的指针转换为另一个的指针。 【注:数组对象与其第一个元素并不是指针可互换的,尽管它们拥有相同的地址。——注释结束】