c++之具有引用成员的结构是否具有唯一的对象表示

softidea 阅读:14 2024-06-20 12:54:19 评论:0

answer提出了以下问题。
假设我们有一个简单的

struct S { 
    int& i; 
} 
内部(至少在 GCC 和 Clang 中) S只包含一个指向 int 的指针, 和
static_assert(sizeof(int*) == 8); 
static_assert(sizeof(S)    == 8); 
是否 S有一个独特的对象表示? GCC 和 Clang 不同意 *:
static_assert( std::has_unique_object_representations_v<int*>); 
static_assert(!std::has_unique_object_representations_v<S>);    // GCC 
static_assert( std::has_unique_object_representations_v<S>);    // Clang 
哪个编译器就在这里,为什么?
* 指出 GCC 和 Clang 之间的分歧idclev 463035818 .

请您参考如下方法:

首先,引用不是对象。对象在 [intro.object] 中指定,引用在 [dcl.ref] 中。
子对象是对象([intro.object])。因此引用成员不是子对象,因此只包含引用成员(没有基类)的类没有子对象(即使它有数据成员)。

[meta.unary.prop]

The predicate condition for a template specialization has_­unique_­object_­representations shall be satisfied if and only if:

  • T is trivially copyable, and
  • any two objects of type T with the same value have the same object representation, where two objects of array or non-union class type are considered to have the same value if their respective sequences of direct subobjects have the same values, ...

子对象的序列是空的,因此等于另一个空序列,因此等于 S 类型的所有对象。根据此规则具有“相同值”2。
但是,引用不同对象的对象必然具有不同的对象表示。因此,第二个要求是 不是 1 满意。
因此对象表示不是唯一的,Clang 在技术上是错误的,而 GCC 和 MSVC(与 GCC 具有相同的结果)是正确的。

如果我们得出不满足第二个要求的结论,这已经变得有点离题了,但是:是 S微不足道的复制?
static_assert(std::is_trivially_copyable_v<S>); 
在 Clang 和 GCC 中都通过,但根据 MSVC, S不是 可复制。那么,哪个是正确的?

[class.copy.ctor]

A copy/move constructor for class X is trivial if it is not user-provided and if:

  • class X has no virtual functions ([class.virtual]) and no virtual base classes ([class.mi]), and
  • the constructor selected to copy/move each direct base class subobject is trivial, and
  • for each non-static data member of X that is of class type (or array thereof), the constructor selected to copy/move that member is trivial;

这些都满足了。因此 S有一个简单的复制/移动构造函数。

[class.prop]

A trivially copyable class is a class:

  • that has at least one eligible copy constructor, move constructor, copy assignment operator, or move assignment operator ([special], [class.copy.ctor], [class.copy.assign]),
  • where each eligible copy constructor, move constructor, copy assignment operator, and move assignment operator is trivial, and
  • that has a trivial, non-deleted destructor ([class.dtor]).

一切都很满意,因此 S 微不足道的可复制,而 MSVC 类型特征相反地陈述是错误的。

1 编辑:我最初得到了反向结论。
2 在考虑类对象的“值”时是否应该忽略引用数据成员在我看来是有争议的。这种忽略它们的技术性可能被视为标准中的缺陷。


标签:C++
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

关注我们

一个IT知识分享的公众号