ここで、VS2005 と 2010 の両方で発生している奇妙な問題があります。インライン関数が呼び出される for ループがあります。本質的には次のようなものです (C++、説明目的のみ)。
inline double f(int a)
{
if (a > 100)
{
// This is an error condition that shouldn't happen..
}
// Do something with a and return a double
}
そして、別の関数のループ:
for (int i = 0; i < 11; ++i)
{
double b = f(i * 10);
}
これで、デバッグ ビルドですべてが正常に動作するようになりました。すべての最適化がオンになっているリリース ビルドでは、これは、逆アセンブルによると、i
なしで直接使用されるようにコンパイルされ* 10
、比較a > 100
は に変わりますがa > 9
、私はそれがa > 10
. a > 9
コンパイラにそれが正しい方法であると思わせる原因について何か手がかりはありますか? 興味深いことに、周囲のコードのマイナーな変更 (たとえば、デバッグの出力) でも、コンパイラはそれを使用i * 10
し、リテラル値の 100 と比較します。
これがやや曖昧であることは承知していますが、古いアイデアに感謝します。
編集:
これは、うまくいけば再現可能なケースです。ここに貼り付けるには大きすぎるとは思わないので、次のようにします。
__forceinline int get(int i)
{
if (i > 600)
__asm int 3;
return i * 2;
}
int main()
{
for (int i = 0; i < 38; ++i)
{
int j = (i < 4) ? 0 : get(i * 16);
}
return 0;
}
これを自分のマシンの VS2010 でテストしたところ、問題が発生している元のコードと同じように動作が悪いようです。リリース構成で、IDE のデフォルトの空の C++ プロジェクト テンプレートを使用して、これをコンパイルして実行しました。ご覧のとおり、ブレークはヒットしないはずです (37 * 16 = 592)。i < 4
を削除すると、元のコードと同じように機能することに注意してください。