让我来上课吧class Drawable
。它可以有许多成员、成员函数、父类,也可以非常简单。对于这个例子来说,这并不重要。另外,假设它是某种 GUI 元素。
然后,假设我有一个渲染引擎,它作为 GCC 库提供engine.a
。该库包含class Screen
,其中有方法void Screen::add(const Drawable & child)
。我所拥有的只是标头和库本身。在我的应用程序中我实例化Screen
,创建几个Drawable
物体和add
他们到Screen
.
我的问题:
我的 GCC 工具链(或我的 GCC 工具链的版本)可以为以下内容创建不同的内存布局吗Drawable
对象比编译中的对象engine.a
?标准没有定义它,它是一个实现细节。无论哪种方式,它都会完美链接。我如何知道这一点以及如何确定行为是否正确?
P.S. 我主要使用 ARM GCC 工具链来实现 Cortex-M 架构。但我的问题不仅限于此.
P.P.S. 如果您有任何相关但与 GCC 无关的想法,请随时分享。
谢谢。
EDIT
这个问题仅与编译器内部有关。
我的 GCC 工具链(或我的 GCC 工具链版本)是否可以为 Drawable 对象创建与编译的 engine.a 不同的内存布局?
是的。考虑下面这个愚蠢的例子:
struct Drawable
{
#ifdef ENABLE_COUNTERS
int counter = 0;
#endif
// ...
};
也许有人编译了-DENABLE_COUNTERS
而其他人则没有。这违反了单一定义规则。或者,可能编译了一个工具链,其中整数为 32 位,而另一个工具链则为 64 位。
链接器为了快,不会抱怨;它只会丢弃除一个定义之外的所有定义,这可能会造成各种破坏(尤其是虚拟函数调用,当偏移量出错时可能会变得很奇怪)。
我如何知道这一点以及如何确定行为是否正确?
gcc has flto-odr-type-merging https://gcc.gnu.org/onlinedocs/gcc-9.1.0/gcc/Optimize-Options.html and -Wodr
这可以在您编译时为您提供帮助。
谷歌的ASAN https://github.com/google/sanitizers/wiki/AddressSanitizerOneDefinitionRuleViolation还可以检查内存布局以确保它们相同。
仅关于您对编译器内部的编辑。
请参考GCC关于ABI稳定性的指南:https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html
Roughly请讲。每个主要编译器版本都有一个新的 ABI。后来的次要版本与相同的主要版本几乎总是兼容的。
您可以控制目标 ABI-fabi-version
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)