c++ - "C++ compilers use a binary object layout"这句话的含义和用途是什么

标签 c++ pointers object memory layout

在浏览此 C++ 常见问题解答时 https://isocpp.org/wiki/faq/mixing-c-and-cpp#cpp-objs-passed-to-c我遇到了语句

Most C++ compilers use a binary object layout that causes this conversion to happen with multiple inheritance and/or virtual inheritance.

我无法理解它的含义和应用。根据 C++ FAQ,此对象布局机制有助于 C++ 编译器进行以下检查

In C++ it is easy to check if a Derived* called dp points to the same object as is pointed to by a Base* called bp: just say if (dp == bp) .... The C++ compiler automatically converts both pointers to the same type, in this case to Base*, then compares them. Depending on the C++ compiler’s implementation details, this conversion sometimes changes the bits of a pointer’s value.

任何人都可以帮助理解任何流行的 C++ 编译器的二进制对象布局,以及指针值的位变化的可能变化和相应机制。以及它如何帮助比较基类/派生类的指针。

编辑:请解释为什么下面的陈述也是有效的。

NOTE: you must be especially careful when converting both to void* since that conversion will not allow either the C or C++ compiler to do the proper pointer adjustments! The comparison (x == y) might be false even if (b == d) is true:

最佳答案

在此上下文中,“二进制对象布局”是指“包含对象的二进制数据如何在内存中布局。”

考虑这个 C++ 代码:

struct Left
{
  int ll;
};

struct Right
{
  int rr;
};

struct Derived : Left, Right
{
  int dd;
};

在内存中组织这些(概念上)的一种可能方法如下:

+ Derived ----------------+
| + Left +  + Right +     |
| | ll   |  | rr    |  dd |
| +------+  +-------+     |
+-------------------------+

当然,这个类只有3个int,所以有了上面的概念布局,真正的布局应该是这样的:

+ Derived------+
| ll | rr | dd |
+--------------+

现在想象一下这段代码:

Derived d;
Dervied *pd = &d;
Left *pl = &d;
Right *pr = &d;

pd 指向d 的开始,与它的ll 成员的开始相同。

pl 将指向 dLeft 子对象。 Left 的开始是 ll 成员的开始。比较pl == pd时,pd需要转换为类型Left*。请记住,pd 已经指向 ll 的开始,因此不需要更改 pd 的值。这纯粹是一种概念转换(类型的改变)。

pr 指向 dRight 子对象。由于 Right 对象以 rr 成员开头,因此 pr 指向 rr。同样,执行 pr == pd 需要将 pd 转换为类型 Right*dRight子对象以rr成员开头,但是pd指向的地址ll 成员。因此,pd 的值(= 位)必须通过此转换更改(增加一个 int 的大小)以指向 rr 代替。实际上,在将 &dDerived* 转换为 Right* 以初始化 pr 时,这个转换已经发生过一次与它。

这也应该解释为什么在 void* 类型中比较不起作用。显然,&d.ll != &d.rr,即使 pl == pr

关于c++ - "C++ compilers use a binary object layout"这句话的含义和用途是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29144356/

相关文章:

c++ - 在运行时确定 *.dll 或 *.so 的路径

c - 动态数组分配,按值传递,超出范围

c++ - 在 C++ 中将二维数组更改为 1 的函数

javascript - 更新 Javascript 对象值给出 null

c++ - 引用参数返回拷贝

c++ - 为什么要实现有限状态机 : run-time error,?

xcode - 遍历对象/变量 Swift

javascript - 与 Laravel 一起运行的 Javascript 中出现意外标识符

c++ - "EXIT_FAILURE"是什么类别?

multithreading - 从 goroutine func 发出修改映射