"C++ compilers use a binary object layout"这句话的含义和用途是什么
What is the meaning and use of the sentence "C++ compilers use a binary object 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++ 常见问题解答,此对象布局机制有助于 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++ 编译器的 二进制对象布局 以及可能的变化以及 位的变化的相应机制指针的值。 以及它如何帮助比较 Base/Derived 类.
的指针
编辑:请解释为什么下面的陈述也是有效的。
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:
在此上下文中,"binary object layout" 表示 "how the binary data comprising the object is layed out in memory."
考虑这个 C++ 代码:
struct Left
{
int ll;
};
struct Right
{
int rr;
};
struct Derived : Left, Right
{
int dd;
};
在内存中组织这些(概念上)的一种可能方法如下:
+ Derived ----------------+
| + Left + + Right + |
| | ll | | rr | dd |
| +------+ +-------+ |
+-------------------------+
当然,class只是3int
秒,所以有了上面的概念布局,真正的布局就是这样:
+ Derived------+
| ll | rr | dd |
+--------------+
现在想象一下这段代码:
Derived d;
Dervied *pd = &d;
Left *pl = &d;
Right *pr = &d;
pd
指向 d
的开始,这与其 ll
成员的开始相同。
pl
将指向 d
的 Left
子对象。 Left
的开头是 ll
成员的开头。比较pl == pd
时,需要将pd
转换为Left*
类型。请记住 pd
已经指向 ll
的开始,因此不需要更改 pd
的值。纯粹是概念上的转换(类型的改变)。
pr
指向 d
的 Right
子对象。由于 Right
对象以 rr
成员开头,因此 pr
指向 rr
。同样,执行 pr == pd
需要将 pd
转换为类型 Right*
。 d
的 Right
子对象以 rr
成员开始,但 pd
指向 ll
成员的地址。因此,pd
的值(= 位)必须通过此转换(增加一个 int
的大小) 更改 以指向 rr
反而。实际上,在将 &d
从 Derived*
转换为 Right*
以便用它初始化 pr
时,这种转换已经发生过一次。
这也可以解释为什么 void*
类型的比较不起作用。显然,&d.ll != &d.rr
,即使 pl == pr
.
在查看此 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++ 常见问题解答,此对象布局机制有助于 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++ 编译器的 二进制对象布局 以及可能的变化以及 位的变化的相应机制指针的值。 以及它如何帮助比较 Base/Derived 类.
的指针编辑:请解释为什么下面的陈述也是有效的。
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:
在此上下文中,"binary object layout" 表示 "how the binary data comprising the object is layed out in memory."
考虑这个 C++ 代码:
struct Left
{
int ll;
};
struct Right
{
int rr;
};
struct Derived : Left, Right
{
int dd;
};
在内存中组织这些(概念上)的一种可能方法如下:
+ Derived ----------------+
| + Left + + Right + |
| | ll | | rr | dd |
| +------+ +-------+ |
+-------------------------+
当然,class只是3int
秒,所以有了上面的概念布局,真正的布局就是这样:
+ Derived------+
| ll | rr | dd |
+--------------+
现在想象一下这段代码:
Derived d;
Dervied *pd = &d;
Left *pl = &d;
Right *pr = &d;
pd
指向 d
的开始,这与其 ll
成员的开始相同。
pl
将指向 d
的 Left
子对象。 Left
的开头是 ll
成员的开头。比较pl == pd
时,需要将pd
转换为Left*
类型。请记住 pd
已经指向 ll
的开始,因此不需要更改 pd
的值。纯粹是概念上的转换(类型的改变)。
pr
指向 d
的 Right
子对象。由于 Right
对象以 rr
成员开头,因此 pr
指向 rr
。同样,执行 pr == pd
需要将 pd
转换为类型 Right*
。 d
的 Right
子对象以 rr
成员开始,但 pd
指向 ll
成员的地址。因此,pd
的值(= 位)必须通过此转换(增加一个 int
的大小) 更改 以指向 rr
反而。实际上,在将 &d
从 Derived*
转换为 Right*
以便用它初始化 pr
时,这种转换已经发生过一次。
这也可以解释为什么 void*
类型的比较不起作用。显然,&d.ll != &d.rr
,即使 pl == pr
.