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 呼び出しがインライン化されていない場合にのみクラッシュが発生することがわかりました。push_back メソッドが複数回呼び出されていることに GCC が気付いた場合、GCC はそれを各場所にインライン化しません。たとえば、main 内で push_back を 2 回呼び出して、クラッシュを再現することもできます。foo を static にすると、gcc はそれが呼び出されないことを認識し、最適化します。その結果、push_back が main にインライン化され、クラッシュが発生しなくなります。

gcc 4.3.3 を使用して x86 でこれを試しましたが、そのバージョンでは問題が修正されているようです。

だから、私の質問は次のとおりです。

他の誰かがこれに遭遇しましたか?おそらく、それを防ぐために渡すことができるコンパイラフラグがいくつかあります。

これは 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 へのアップグレードは安全な賭けです。そのコード生成バックエンドは、古い RTL (Register Transfer Language) 表現を SSA (Static Single Assignment) に置き換えます。この変更により、オプティマイザを大幅に書き直すことができました。

于 2010-01-19T11:14:31.887 に答える