为什么-O2中的编译会使我的应用程序崩溃,但-O2 -fno-default-inline不会?

时间:2010-02-08 17:19:18

标签: c++

我有一个名为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?

,似乎在分配字符串名称时发生了崩溃

5 个答案:

答案 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)

优化设置导致的错误很少见。我打赌你的程序中的某个地方你依赖于未定义或不可靠的行为,它应该一直崩溃,但偶然的机会不会因特定的优化设置而崩溃。我会说这是你做错的其他事情,而不是你的优化标志。