今日、プロジェクトをコンパイルしようとしましたが、これまで複数のプラットフォームでこのプロジェクトをコンパイルする際に問題が発生したことはありませんでしたが、g++ (4.2.1) をリリース モード (-O2 最適化フラグを使用) で使用して Mac OS X で試してみると、コンパイルが同じファイルで永遠に動かなくなる。コードをいじって、問題を本質的に次のコードに絞り込みました。
void MyClass::SendBigMessage()
{
int Offset = 0;
PackByteArrayIntoMessage(SomeDataArray1, SomeDataArray1Size, Offset);
PackByteArrayIntoMessage(SomeDataArray2, SomeDataArray2Size, Offset);
// ...snip
PackByteArrayIntoMessage(SomeDataArray9, SomeDataArray9Size, Offset);
PackByteArrayIntoMessage(SomeDataArray10, SomeDataArray10Size, Offset);
SendMessage(Message);
}
void MyClass::PackByteArrayIntoMessage(unsigned char *ByteArray, int Size, int &Offset)
{
for(int i = 0; i < Size; i++)
{
Message.SetByteAtOffset(ByteArray[i], Offset++);
}
}
ファイルの本体をコメントアウトするPackByteArrayIntoMessage
と、ファイルは問題なくコンパイルされます。また、 へのすべての呼び出しをコメント アウトしPackByteArrayIntoMessage
、関数の本体をコメント インしたままにすると、ファイルは問題なくコンパイルされます。より多くの呼び出しでコメントを開始すると、コンパイル時間が指数関数的に長くなるように見え、約 10 回の連続呼び出しで、ファイルのコンパイルが永遠にハングアップするように見えます。
gcc が巧妙な最適化を行おうとしていると推測したので、PackByteArrayIntoMessage
コンパイルが再開されるまでいじってみたところ、この実装は問題なく動作しました。
void MyClass::PackByteArrayIntoMessage(unsigned char *ByteArray, int Size, int &Offset)
{
for(int i = 0; i < Size; i++)
{
Message.SetByteAtOffset(ByteArray[i], Offset + i);
}
Offset = Offset + Size;
}
Linux で -O2 を使用して gcc 4.4.0 でコンパイルすると、コードを変更しなくても問題なく動作するため、これは gcc 4.2.1 のバグであるとしか思えません。
だから私の質問は、ハングの問題を引き起こすコンパイラが何をしようとしているのかということです。いくつかの gcc バージョンのリリース ノートを調べましたが、この特定の問題について言及しているものは見つかりませんでした。また、最適化されていないことを確認するためにコード セグメントをマークする方法はありますか?