我有一个名为TheLib的第三方库,我的lib名为MyLib
首先编译TheLib,并在一个名为variantmap.h的头文件中包含一个Struct。此标头包含2个内联函数:
struct VariantMap {
string name;
map<string, Variant> children;
bool isArray;
VariantMap(VariantMap & variantMap) {
name = variantMap.name;
children = variantMap.children;
isArray = variantMap.isArray;
}
VariantMap() {
isArray = false;
}
};
MyLib也会使用前面提到的标题进行编译。
当我使用-O2(优化级别)编译两个lib时,MyLib崩溃了,但是如果我用-O2编译MyLib但没有内联函数(即-fno-default-inline),则不会????
根据gdb?
,似乎在分配字符串名称时发生了崩溃答案 0 :(得分:2)
我不知道Linux上的这个问题(在g ++上没有足够的经验),但在Windows上,它混合在一起混合了不兼容的运行时,所以我想我的回答可能会给你一些有限的见解......
首先猜测,可能是因为TheLib和MyLib具有相同功能的不同实现。
如果“复制构造函数”被内联到“MyLib”中,那么代码将使用MyLib编译的复制构造函数代码实现(即字符串赋值)。
另一方面,如果对复制构造函数的调用不是“内联”,那么对复制构造函数的调用可能会调用在TheLib中编译的代码。
想象一下,在TheLib和MyLib中,无论出于何种原因,字符串赋值都是不同的,那么崩溃并不令人意外。也许MyLib正在使用支持COW的字符串,而TheLib使用更简单的字符串实现。
另一个可能的问题来源是不同的分配器。 TheLib的malloc不是MyLib的malloc,因此,尝试重新分配字符串的缓冲区以容纳副本也会导致崩溃。
答案 1 :(得分:1)
这不是一个好的复制构造函数:
VariantMap(VariantMap & variantMap) {
name = variantMap.name;
children = variantMap.children;
isArray = variantMap.isArray;
}
首先,它没有做任何默认的复制构造函数不会做得更好,其次它没有const引用作为参数。另外,由于你提供了一个复制构造函数,大概你也有一个赋值操作和一个析构函数?他们看起来怎么样?最后,Variant(不是VariantMap)真的可以复制吗?请记住,错误出现的地方通常只是它显示的地方。
答案 2 :(得分:0)
您是否在所有内容中使用相同版本的C-Run-time?某些编译器套件仅向头文件添加仅调试信息(例如)。如果使用DEBUG预处理器标志编译“TheLib”,并且您正在编译而没有,例如,则会发生不匹配。它崩溃可能只是随机的。您是否确保数据的正确性不会崩溃?
答案 3 :(得分:0)
您发布的内容不足以确定问题。我怀疑Variant类没有正确处理引用。这个问题可能只是对最优化水平的意外:一个人无声地失败而另一个人大声失败。
答案 4 :(得分:0)
优化设置导致的错误很少见。我打赌你的程序中的某个地方你依赖于未定义或不可靠的行为,它应该一直崩溃,但偶然的机会不会因特定的优化设置而崩溃。我会说这是你做错的其他事情,而不是你的优化标志。