3

たくさんのTNotifyEventsベクターに入れるコードがあります。

std::vector<TNotifyEvent> m_availableCallbacks;

これは、アプリケーションのメインフォームのメンバーです。フォームコンストラクターでは、イベントで埋められます。

m_availableCallbacks.push_back(ReadoutLastValue);
m_availableCallbacks.push_back(ReadoutCurrentDay);
m_availableCallbacks.push_back(ReadoutLastDay);
m_availableCallbacks.push_back(Readout7Days);
m_availableCallbacks.push_back(Readout1Month);
m_availableCallbacks.push_back(ReadoutChooseTimeSpan);
m_availableCallbacks.push_back(ReadoutAllData);

次に、このベクトルが繰り返され、ポップアップメニューを作成し、そのポップアップメニューの要素に通知イベントを割り当てるために使用されます。

これをローカルでコンパイルしても問題はありません。ビルドサーバー(TeamCity 6.5を実行している)でコンパイルすると、2番目のpush_back呼び出しに等しい行で内部コンパイラエラーが発生します。

cbprojファイルを編集して、ビルドエージェントでローカルにスマートキャッシュのプリコンパイル済みヘッダーを無効にしてみました。これにより、ビルドが成功しました。そこで、すべてのcbprojファイルからスマートキャッシュのプリコンパイル済みヘッダーを使用するディレクティブを削除し、変更をコミットしました。TeamCityクリーンチェックアウトを実行するように指示しましたが、同じ場所で同じ内部コンパイラエラーが発生しました。奇妙なことに、失敗したコンパイルの後に新しいコンパイルを実行すると成功するため、これは非常にランダムに感じられます。

何が起こっている?私は他のC++コンパイラで関数ポインタ(自分で作成したもの)をうまく渡すことに慣れています。TNotifyEventsの内部処理が壊れていますか、それともコンパイラが不安定で簡単に壊れていますか?

TNotifyEventsを取得する他のコードを見ると、参照やポインターでは機能しないため、私はそれを試しませんでした。また、コード(コンパイル時)は意図したとおりに機能するため、問題はないようです。

アップデート:

TeamCityのログには、コンパイルを再実行して成功したときにFrontEnd.cppファイル(このコードが含まれている)がスキップされることが示されていることを追加できます。

[10:04:37]: [MakeObjs] CallTarget
[10:04:37]:   [CallTarget] _CppDepCheck
[10:04:44]:     [_CppDepCheck] MessageMap
[10:04:44]:       [MessageMap] Skipping: ..., FrontEnd.cpp, ...

そしてそれが機能するためには、内部コンパイラエラーが発生したときにコンパイルが成功している必要があります。それ以外の場合、ファイルのコンパイルをスキップし、それでも魔法のように表示され、コンパイルされた形式で使用されるようにするにはどうすればよいでしょうか。:)

Update2

調査の結果、これはリリースモードでコンパイルした場合にのみ発生することが確認できました。リリースでは、IDEのローカルマシンでも発生します。私は次のような設定をいじってみました

  • すべての最適化を無効にする
  • 可能な限り最速のコードを生成する
  • 外部タイプファイル
  • 等々

各試行の間にビルドをクリーニングします。しかし、ICEは消えません。しかし、私はなんとか別のファイルの別の場所について文句を言うことができました。設定を以前の状態に戻しても、エラーがFrontEnd.cppファイルに戻ることはありません。このコンパイラはちょっと不安定に感じます:)

実際、私はコード全体でICEを取得し始め、何でもコンパイルできるようにするためにIDEを再起動する必要がありました。

4

1 に答える 1

0

これはstd::vectorと関連しているようです。それ自体が壊れているのか、それともbccによって処理される方法が問題なのかはわかりません。しかし、代わりにテストとして C スタイルの配列に切り替えると、ICE がなくなり、デバッグ モードとリリース モードの両方で正常に動作するようになりました。

TNotifyEvent m_availableCallbacks[7];

ベクターに新しいイベントを追加するには、ほとんど 1 行のコードしか必要ないため、これを避けたかったのです。これで、変更するために覚えておくべきことがもう少しあります。ただし、アプリケーションをコンパイルした方がよいでしょう。

これが BCC のバグであるという私の考えが間違っている場合は、できるだけ早くベクターを使用できるように修正してください :)... そうでない場合は、Embarcadero がこれをできるだけ早く修正してくれることを願っています。

于 2012-05-30T13:43:16.180 に答える