1

以下代码对我使用 GCC 为 ARM 构建时崩溃:

#include <vector>

using namespace std;

void foo(vector<bool>& bools) {
    bools.push_back(true);
}

int main(int argc, char** argv) {

    vector<bool> bools;
    bool b = false;
    bools.push_back(b);
}

我的编译器是:arm_v5t_le-gcc (GCC) 3.4.3 (MontaVista 3.4.3-25.0.30.0501131 2005-07-23). 为调试而构建时不会发生崩溃,但会在优化设置为 -O2 时发生。

是的, foo 函数是重现问题所必需的。起初这很令人困惑,但我发现只有在 push_back 调用未内联时才会发生崩溃。如果 GCC 注意到 push_back 方法被多次调用,它不会在每个位置内联它。例如,我还可以通过在 main 中调用 push_back 两次来重现崩溃。如果您将 foo 设为静态,则 gcc 可以判断它永远不会被调用并对其进行优化,从而导致 push_back 内联到 main 中,从而导致崩溃不会发生。

我已经在 x86 上使用 gcc 4.3.3 进行了尝试,看来该版本的问题已解决。

所以,我的问题是:

有没有其他人遇到过这个?也许我可以传入一些编译器标志来防止它。

这是 gcc 代码生成的错误,还是 stl 实现(bits/stl_bvector.h)中的错误?(我计划有时间自己测试一下)

如果是编译器的问题,是升级到 4.3.3 来修复它,还是从 arm 切换到 x86?

顺便说一句,大多数其他vector<bool>方法似乎都有效。是的,我知道使用vector<bool>并不是世界上最好的选择。

4

2 回答 2

1

你能用 gcc 3.4.6 和 Montavista 的补丁构建你自己的工具链吗?3.4.6 是 3.x 系列的最后一个版本。

如果需要,我可以附加一些关于如何从 GCC 源代码构建 ARM 交叉编译器的说明。我必须一直这样做,因为没有人为 Mac OS X 预先构建工具链。

如果这在 gcc 4.x 中被 ARM 破坏,我会感到非常惊讶。但唯一的测试方法是您或其他人是否可以在面向 ARM 的 gcc 4.x 上进行尝试。

于 2010-01-19T04:05:00.767 回答
1

升级到 GCC 4 是一个安全的选择。它的代码生成后端用 SSA(静态单一分配)替换旧的 RTL(寄存器传输语言)表示。此更改允许对优化器进行重大重写。

于 2010-01-19T11:14:31.887 回答