C++ 混合单独编译的对象
让我有一个类C++ 混合单独编译的对象,c++,gcc,C++,Gcc,让我有一个类可以绘制的类。它可以有许多成员、成员函数、父类,也可以非常简单。为了这个例子,这并不重要。另外,假设它是某种GUI元素 然后,假设我有一个渲染引擎,它是作为GCC库引擎提供的。该库包含类屏幕,它具有方法void Screen::add(const Drawable&child)。我只有标题和库本身。在我的应用程序中,我实例化Screen,创建一些可绘制的对象,并将它们添加到Screen 我的问题: 我的GCC工具链(或我的GCC工具链版本)是否可以为可绘制的对象创建与编译的引擎.a不
可以绘制的类
。它可以有许多成员、成员函数、父类,也可以非常简单。为了这个例子,这并不重要。另外,假设它是某种GUI元素
然后,假设我有一个渲染引擎,它是作为GCC库引擎提供的。该库包含类屏幕
,它具有方法void Screen::add(const Drawable&child)
。我只有标题和库本身。在我的应用程序中,我实例化Screen
,创建一些可绘制的对象,并将它们添加到Screen
我的问题:
我的GCC工具链(或我的GCC工具链版本)是否可以为可绘制的
对象创建与编译的引擎.a
不同的内存布局?标准并没有定义它,它是一个实现细节。无论哪种方式,它都会完美地连接在一起。我如何知道这一点,如何确定正确的行为
另外,对于Cortex-M架构,我主要使用ARM GCC工具链但我的问题不仅限于此
另外,如果您有任何与GCC相关但与GCC无关的想法,请随时与我们分享
多谢各位
编辑
这个问题只涉及编译器内部。内存布局以及许多其他内容是ABI的一部分。另一件事是名称篡改方案。尽管您应该只将为同一ABI编译的对象链接在一起,但ABI设计者尝试使用不同的损坏方案,因此意外地链接使用不同ABI编译的对象通常会导致无法解析的符号
GCC有一个命令行标志来控制ABI:-fabi version
,但ABI还依赖于一些其他选项,如-fno exceptions
,显然还依赖于标准类型的标准库实现
我的GCC工具链(或我的GCC工具链版本)是否可以为可绘制对象创建与编译引擎中不同的内存布局
对。考虑下面的愚蠢例子:
struct Drawable
{
#ifdef ENABLE_COUNTERS
int counter = 0;
#endif
// ...
};
也许有一个人使用-DENABLE_计数器编译,而其他人没有。这违反了“一个定义”规则。或者可能有一个工具链编译时整数为32位,另一个编译时整数为64位
链接器,为了快速,不会抱怨;它只会扔掉除一个定义之外的所有定义,这可能造成各种破坏(特别是当偏移量出错时,虚拟函数调用可能会变得怪异)
我如何知道这一点,如何确定正确的行为
gcc有和-Wodr
,可以在编译时帮助您
谷歌还可以检查内存布局,以确保它们完全相同
关于您对编译器内部的编辑
请参考GCC关于ABI稳定性的指南:
粗略地说。每个主要的编译器版本都有一个新的ABI。稍后的次要版本与相同的主要版本几乎总是兼容的
您可以使用-fabi version
控制目标ABI。您的库和代码应至少在编译器的相同主版本中编译。是。对于非标准布局类型,很可能存在ODR冲突:只有使用相同的编译器+设置,它才能得到很好的定义。这基本上是您的选择,a)仅使用标准布局类型或b)相同的编译器+settings@NathanOliver理论上,当然。在实践中,主要编译器的C++ abi在很久以前没有改变,甚至可以链接到古图书馆而没有问题。ABI更改对于编译器供应商来说几乎是禁忌。事实上,这是一个主要的症结所在,因为它会导致标准库实现中出现不寻常的(~5倍)性能退化,这需要更改ABI来修复。也许这将在未来五年内发生变化(对ABI兼容性的抵抗正在慢慢形成),但到目前为止,我仍然持怀疑态度。@KonradRudolph您能为您的~5倍陈述提供参考吗?我想读更多关于这方面的内容,我的问题不是不同的编译选项会影响输出。问题只是关于编译器内部的。那个么你们对GCC版本之间的ABI稳定性感兴趣:这里并没有关于名称混乱。我并没有改变函数原型,所以它不会影响任何东西。链接器将100%完美通过。请参阅我在原始帖子中的编辑。