ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

c – 将对象的第一个字段转换为对象的类型实际上是否安全?

2019-09-01 14:08:38  阅读:128  来源: 互联网

标签:c undefined-behavior casting


乍一看,这看起来像未定义的行为……

#include <iostream>

struct SomeBaseClass
{
    // ...
};

struct MyFakerClass
{
    SomeBaseClass base;
    void foo() { std::cout << "hello" << std::endl; }
};

int main()
{
    MyFakerClass c;
    MyFakerClass *p = static_cast<MyFakerClass *>(static_cast<void *>(&c.base));
    p->foo();
}

…但是如果保证对象的第一个字段与对象具有相同的地址,那么这一定是安全的,对吧?还是有其他一些干预的规则吗?

解决方法:

A pointer to a standard-layout struct object, suitably converted using a reinterpret_cast, points to its initial member (or if that member is a bit-field, then to the unit in which it resides) and vice versa. [ Note: There might therefore be unnamed padding within a standard-layout struct object, but not at its beginning, as necessary to achieve appropriate alignment. — end note ]

(C 11,§9.2,¶21)

所以,只要一个类是“标准布局”,这就是安全的,即:

A standard-layout class is a class that:

  • has no non-static data members of type non-standard-layout class (or array of such types) or reference,
  • has no virtual functions (10.3) and no virtual base classes (10.1),
  • has the same access control (Clause 11) for all non-static data members,
  • has no non-standard-layout base classes,
  • either has no non-static data members in the most derived class and at most one base class with non-static data members, or has no base classes with non-static data members, and
  • has no base classes of the same type as the first non-static data member.

(C 11,§9,¶7)

关于虚拟东西的所有要求都是因为vptr:如上所述,许多编译器把它作为第一个隐藏成员,但允许它们放在任何地方,或者,如果它们能够,可以省略它或实现虚拟以其他方式调度,因此虚拟通常以未指定的方式改变类的布局.

“相同的访问控制条款”是因为

The order of allocation of non-static data members with different access control is unspecified.

(C 11,§9.2,¶15)

我想这可能是允许编译器通过访问控制重新排序/分组类的成员(即在编译器内部,类的IR可能包含每个访问控制说明符下的成员列表,这不允许保持原始排序 – 所有交错的公共/私有/受保护部分将被分组,例如私有成员可以默认放在类前面).

没有非标准布局成员/基类“递归”子句是为了确保该类是标准布局作为一个整体(基类和成员是它的一部分).

有关其他内容可能影响类布局的其他详细信息,请参见§9.2.

请注意,这是一个比POD类弱的条件(正如我在上面的注释中错误地说的那样),因为如果一个类是POD,那么它是标准布局和平凡(§9¶10)

标签:c,undefined-behavior,casting
来源: https://codeday.me/bug/20190901/1783523.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有