问题描述
C ++标准的当前草案(2019年3月)具有以下段落([basic.types] p.4)(强调我的意思):
The current draft of the C++ standard (march 2019) has the following paragraph ([basic.types] p.4) (emphasis mine):
为什么突出显示的句子仅限于可复制的类型?是因为不可平凡对象的值表示形式中的某些位可能不在其对象表示形式中吗?此答案以及这个暗示了这一点.
Why is the highlighted sentence limited to trivially copyable types? Is it because some bits from the value representation of a non-trivially-copyable object may be outside its object representation? This answer, as well as this one imply this.
但是,在上面链接的答案中,对象的概念性值是基于用户引入的语义的.在第一个链接的答案的示例中:
However, in the answers linked above, the conceptual value of the object is based on semantics that are introduced by the user. In the example from the first linked answer:
class some_other_type
{
int a;
std::string s;
};
用户确定类型为 some_other_type
的对象的 value 包含属于字符串 s
的字符.
the user decides that the value of an object of type some_other_type
includes the characters belonging to string s
.
我试图考虑一些示例,其中某个对象的某些位(不是不可复制的)值表示不在其对象表示是隐式的(实现必须这样做,它不是由用户任意决定的.)
I tried to think of examples where the fact that some bits of an object's (that is not trivially copyable) value representation are outside its object representation is implicit (the implementation has to do this, it is not arbitrarily decided by the user).
我想到的一个例子是,带有虚拟方法的基类子对象的值表示形式可能包含完整对象的 object表示形式中的位它所属的对象的原因是,与子类本身是完整对象本身的情况相比,基类子对象的行为可能有所不同(可能具有不同的值").
One example that I came up with is the fact that the value representation of a base class subobject with virtual methods may include bits from the object representation of the complete object to which it belongs, because the base class subobject may behave differently (may "have a different value") compared to the situation in which it would be a complete object itself.
我想到的另一个例子是, vtable 也可能是其 vtable指针的对象的值表示的一部分.指向它.
Another example that I though of is the fact that a vtable may also be part of the value representation of the object whose vtable pointer points to it.
这些例子正确吗?还有其他例子吗?
Are these examples correct? Are there other examples?
是由标准委员会引入的突出显示的句子是由于以下事实:对象的语义值"可以由用户确定(如在两个链接的答案中一样),或者是由于实现方式可以确定(或可能被迫)执行此操作,或者两者都执行?
Was the highlighted sentence introduced by the standard committee because of the fact that the semantic "value" of an object may be decided by the user (as in the two linked answers), or because of the fact that implementations may decide (or may be forced) to do this, or both?
谢谢.
推荐答案
在我的解释中,您突出显示的句子的重点是这一部分:
In my interpretation, the focus of the sentence you highlighted is this part:
本质上,该标准的[basic.types]#4表示每个对象都有一组位 O
作为其对象表示形式,一组位是其值表示形式V
.没有V 的 P = O集是填充位.对于普通可复制类型,
V
是 O
".后者很重要,因为这意味着对于琐碎可复制的类型,在 O
位的位周围进行复制还可以在 V
周围安全地进行复制,从而保留了该值.此处无需为其他类型定义 V
的方式(如果需要,可以将其设置为整个抽象机).
Essentially, [basic.types]#4 of the standard says "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
". The latter is important because it means that copying around the O
set of bits also safely copies around the V
for trivially copyable types, thus the value is preserved. How you define V
for other types is of no concern here (set it to the entire abstract machine if you want).
要回答评论中提出的修订问题:
To answer the revised question asked in the comments:
让我们以 std :: string
为例.它不可复制,因为它必须处理内存管理.
Let's take std::string
as an example. It is not trivially copyable because it has to deal with memory management.
如果两个 std :: string
对象具有相同的位模式,它们的意思相同吗?
If two std::string
objects had the same bit pattern, would they mean the same thing?
不.有至少一个实现,它通过对其进行小字符串优化来表示缓冲区指针指向自身(gcc).销毁后,当(且仅当)缓冲区未指向该确切位置时,该缓冲区才被释放.
No. There is at least one implementation that indicates small string optimization by having its buffer pointer point into itself (gcc). Upon destruction, the buffer is deallocated if (and only if) it is not pointing to that exact location.
很明显,在此实现中,位于不同位置的两个 std :: string
对象必须(在此实现中)用不同位模式表示相同(小的)字符串值(缓冲区指针必须是不同的).而且更重要的是,两个对象中相同的位模式可能意味着非常不同的东西-在一种情况下可能表示SSO,而在另一种情况下则不是.
Clearly, two std::string
objects residing in different locations would have to (in this implementation) represent the same (small) string value with different bit patterns (the buffer pointers would have to be different). And more importantly, the same bit pattern in two objects can mean very different things - it might indicate SSO in one case but not the other.
如您所见,每个 std :: string
的值表示中都包含其他信息:这里在内存中的位置(即 this
的值).该标准没有进一步规定以位表示的精确度.
As you can see, there is additional information participating in the value representation of each std::string
here: Its location in memory (i.e. the value of this
). How exactly that is represented in terms of bits is not further specified by the standard.
这篇关于非平凡可复制类型的C ++值表示形式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!