不可平凡复制类型的 C++ 值表示

C++ value representation of non-trivially-copyable types

C++ 标准的当前草案(2019 年 3 月)有以下段落([basic.types] 第 4 页)(强调我的):

The object representation of an object of type T is the sequence of N unsigned char objects taken up by the object of type T, where N equals sizeof(T). The value representation of an object of type T is the set of bits that participate in representing a value of type T. Bits in the object representation that are not part of the value representation are padding bits. For trivially copyable types, the value representation is a set of bits in the object representation that determines a value, which is one discrete element of an implementation-defined set of values.

为什么突出显示的句子仅限于 可简单复制 类型?是因为 非平凡可复制 对象的 值表示 中的某些位可能在其 对象表示之外 ? , as well as this one 暗示这个。

但是,在上面链接的答案中,对象的概念 是基于用户引入的语义。在第一个链接答案的示例中:

class some_other_type
{
    int a;
    std::string s;
};

用户决定 some_other_type 类型对象的 包含属于字符串 s.

的字符

我试着想一些例子,其中一个对象的某些位(不是平凡可复制值表示是在其对象表示之外是隐含的(实现必须这样做,它不是由用户任意决定的)。

我想到的一个例子是 具有虚拟方法的基础 class 子对象的值表示 可能包含来自 object representation 它所属的完整对象,因为基础 class 子对象与它本身是一个完整对象的情况相比可能表现不同(可能 "have a different value") .

我想到的另一个例子是 vtable 也可能是对象的 值表示 的一部分 vtable指针指向它。

这些例子正确吗?还有其他例子吗?

是标准委员会引入的突出显示的句子,因为对象的语义 "value" 可能由用户决定(如两个链接的答案),或者因为这样的事实实现可能会决定(或可能被迫)这样做,或两者兼而有之?

谢谢。

在我的解读中,你强调的句子重点是这部分:

For trivially copyable types, the value representation is a set of bits in the object representation that determines a value, which is one discrete element of an implementation-defined set of values.

基本上,[basic.types]标准的#4 说 "each object has a set of bits O that are its object representation and a set of bits that are its value representation V. The set P = O without V are the padding bits. For trivially copyable types, V is a subset of O"。后者很重要,因为它意味着围绕 O 位集进行复制也可以安全地围绕 V 复制普通可复制类型,因此该值得以保留。如何为其他类型定义 V 在这里无关紧要(如果需要,可以将其设置为整个抽象机)。


回答评论中提出的修改后的问题:

why can't an implementation tell what 1110000100010001111 means if it were the object representation of a non-trivially-copyable object? Is it because there are some other bits (outside of this object representation) that help decide what value the object has?

我们以std::string为例。它不是简单可复制的,因为它必须处理内存管理。

如果两个 std::string 对象具有相同的位模式,它们表示相同的东西吗?

没有。 通过将其缓冲区指针指向自身 (gcc) 来指示小字符串优化。销毁时,如果(且仅当)缓冲区未指向该确切位置时,缓冲区将被释放。

显然,位于不同位置的两个 std::string 对象必须(在此实现中)表示具有 不同 位模式的相同(小)字符串值(缓冲区指针必须不同)。更重要的是,两个对象中的相同位模式可能意味着非常不同的事情——它可能在一种情况下表示 SSO,而在另一种情况下则不表示。

如您所见,这里有其他信息参与每个 std::string 的值表示:它在内存中的位置(即 this 的值)。标准没有进一步详细说明如何用位表示。