混合单独编译的对象 [英] Mixing separately compiled objects
问题描述
让我上一堂课class Drawable
.它可能有许多成员,成员函数,父类,或者可能非常简单.对于此示例而言,这并不重要.另外,我们可以说它是某种GUI元素.
然后,让我们假设我有一个渲染引擎,该引擎作为GCC库engine.a
提供.该库包含class Screen
,它具有方法void Screen::add(const Drawable & child)
.我所拥有的只是标题和库本身.在我的应用程序中,我实例化了Screen
,创建了几个Drawable
对象,并将它们add
创建为Screen
.
我的问题:
我的GCC工具链(或我的GCC工具链的版本)是否可以为Drawable
对象创建与已编译的engine.a
不同的内存布局? Standard未定义它,而是实现的详细信息.无论哪种方式,它都将完美地链接在一起.我怎么知道,如何确定正确的行为?
P. S.我主要将ARM GCC工具链用于Cortex-M架构. 但是我的问题不仅限于此.
P. P. S.如果您有任何相关想法,但与GCC无关,请随时与我们分享.
谢谢.
编辑
此问题仅与编译器内部有关.
我的GCC工具链(或我的GCC工具链的版本)是否可以为Drawable对象创建与已编译engine.a中不同的内存布局?
是的.考虑以下愚蠢的示例:
struct Drawable
{
#ifdef ENABLE_COUNTERS
int counter = 0;
#endif
// ...
};
也许一个人使用-DENABLE_COUNTERS
进行编译,而其他人则没有.这违反了一个定义规则.又或者编译了一个工具链,其中整数是32位,而另一个工具链是64位.
为了快速,链接器不会抱怨;它只会丢弃一个定义之外的所有定义,这可能造成各种破坏(尤其是虚拟函数调用可能会在偏移量变为错误时变得很奇怪).
我怎么知道?如何确定正确的行为?
gcc具有 flto-odr-type-merging
和-Wodr
可以在编译时为您提供帮助.
Google的 ASAN 也可以检查内存布局以确保它们相同. /p>
仅关于编译器内部的编辑.
请参考GCC关于ABI稳定性的指南: https://gcc. gnu.org/onlinedocs/libstdc++/manual/abi.html
大致.每个主要的编译器版本都有一个新的ABI.具有主要版本的次要版本以后的版本几乎总是兼容的.
您可以通过-fabi-version
Let's I have a class class Drawable
. It could have many members, member functions, parent classes, or could be very simple. For the sake of this example that is not important. Also, let's say it is some kind of GUI element.
Then, let's assume I have a rendering engine, which is provided as a GCC library engine.a
. That library contains class Screen
, which has method void Screen::add(const Drawable & child)
. All I have are headers and library itself. In my application I instantiate Screen
, create few Drawable
objects and add
them to Screen
.
My question:
Could my GCC toolchain (or my GCC toolchain's version) create different memory layout for Drawable
objects than in compiled engine.a
? Standard does not define it and it is an implementation detail. Either way it will link perfectly. How can I know that and how can I be sure about correct behaviour?
P. S. I mostly use ARM GCC toolchain for Cortex-M architecture. But my question is not limited to that.
P. P. S. If you have any thoughts related, but not related to GCC specifically, please feel free to share.
Thank you.
EDIT
This question is about compiler internals ONLY.
Could my GCC toolchain (or my GCC toolchain's version) create different memory layout for Drawable objects than in compiled engine.a?
Yes. Consider the following silly example:
struct Drawable
{
#ifdef ENABLE_COUNTERS
int counter = 0;
#endif
// ...
};
Perhaps one person compiled with -DENABLE_COUNTERS
and someone else didn't. This violates the One Definition Rule. Or perhaps one toolchain was compiled where integers were 32 bits and another where they were 64 bits.
The linker, in order to be fast, will not complain; it will just throw away all but one definition, which could wreak all kinds of havoc (virtual function calls especially could get weird as the offsets become wrong).
How can I know that and how can I be sure about correct behaviour?
gcc has flto-odr-type-merging
and -Wodr
that can help you out when you compile.
Google's ASAN can also examine memory layouts to ensure they're identical.
Regarding your edit on compiler internals only.
Please refer to GCC's guidance on ABI stability: https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html
Roughly speaking. Each major compiler version has a new ABI. Later minor releases with the same major release almost always are compatible.
You can control which ABI you target with -fabi-version
这篇关于混合单独编译的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!