GCC 3.4.3 中的 vector::push_back 错误?
使用 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
方法似乎都可以工作。是的,我知道使用 vector
并不是世界上最好的选择。
The following code crashes for me using GCC to build for 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);
}
My compiler is: arm_v5t_le-gcc (GCC) 3.4.3 (MontaVista 3.4.3-25.0.30.0501131 2005-07-23)
. The crash doesn't occur when building for debug, but occurs with optimizations set to -O2.
Yes, the foo function is necessary to reproduce the issue. This was very confusing at first, but I've discovered that the crash only happens when the push_back call isn't inlined. If GCC notices that the push_back method is called more than once, it won't inline it in each location. For example, I can also reproduce the crash by calling push_back twice inside of main. If you make foo static, then gcc can tell it is never called and will optimize it out, resulting in push_back getting inlined into main, resulting in the crash not occurring.
I've tried this on x86 with gcc 4.3.3, and it appears the issue is fixed for that version.
So, my questions are:
Has anyone else run into this? Perhaps there are some compiler flags I can pass in to prevent it.
Is this a bug with gcc's code generation, or is it a bug in the stl implementation (bits/stl_bvector.h)? (I plan on testing this out myself when I get the time)
If it is a problem with the compiler, is upgrading to 4.3.3 what fixes it, or is it switching to x86 from arm?
Incidentally, most other vector<bool>
methods seem to work. And yes, I know that using vector<bool>
isn't the best option in the world.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以使用 gcc 3.4.6 和 Montavista 的补丁构建自己的工具链吗? 3.4.6 是 3.x 系列的最后一个版本。
如果您愿意,我可以附加一些有关如何从 GCC 源代码构建 ARM 交叉编译器的说明。我必须一直这样做,因为没有人为 Mac OS X 预先构建工具链。
如果这在 gcc 4.x 中的 ARM 中被破坏,我会感到非常惊讶。但唯一的测试方法是您或其他人是否可以在面向 ARM 的 gcc 4.x 上尝试此操作。
Can you build your own toolchain with gcc 3.4.6 and Montavista's patches? 3.4.6 is the last release of the 3.x line.
I can append some instructions for how to build an ARM cross-compiler from GCC sources if you want. I have to do it all the time, since nobody does prebuilt toolchains for Mac OS X.
I'd be really surprised if this is broken for ARM in gcc 4.x. But the only way to test is if you or someone else can try this out on an ARM-targeting gcc 4.x.
升级到 GCC 4 是一个安全的选择。其代码生成后端用 SSA(静态单赋值)替换了旧的 RTL(寄存器传输语言)表示形式。此更改允许对优化器进行重大重写。
Upgrading to GCC 4 is a safe bet. Its code generation backend replaces the old RTL (Register Transfer Language) representation with SSA (Static Single Assignment). This change allowed a significant rewrite of the optimizer.