g ++ 4.8.3のバグがいくつか発生したと私は確信していますが、 setjmp/longjmp。私は、次のfoo.cxxに問題の私のコードを単純化しています一貫性のない警告:変数が 'longjmp'または 'vfork'で詰まっている可能性があります
#include <setjmp.h>
#include <string.h>
// Changing MyStruct to be just a single int makes the compiler happy.
struct MyStruct
{
int a;
int b;
};
// Setting MyType to int makes the compiler happy.
#ifdef USE_STRUCT
typedef MyStruct MyType;
#elif USE_INT
typedef int MyType;
#endif
void SomeFunc(MyType val)
{
}
static void static_func(MyType val)
{
SomeFunc(val);
}
int main(int argc, char **argv)
{
jmp_buf env;
if (setjmp(env))
{
return 1;
}
MyType val;
#ifdef USE_STRUCT
val.a = val.b = 0;
#elif USE_INT
val = 0;
#endif
// Enabling the below memset call makes the compiler happy.
//memset(&val, 0, sizeof(val));
// Iterating 1 or 2 times makes the compiler happy.
for (unsigned i = 0; i < 3; i++)
{
// calling SomeFunc() directly makes the compiler happy.
static_func(val);
}
return 0;
}
私はこのコードをコンパイルするG ++ 4.8.3を使用します。興味深いのは、USE_STRUCTを定義すると、コンパイルは失敗しますが、USE_INTで成功するということです。コードには、USE_STRUCTを使用してコンパイルを成功させる方法を示すコメントがあります。コンパイルはg ++の-fPICオプションでも失敗しますが、これは私の環境で必須の引数です。コンパイル・エラー表示するには
:
g++ -DUSE_STRUCT -Wextra -Wno-unused-parameter -O3 -Werror -fPIC foo.cxx
foo.cxx: In function ‘int main(int, char**)’:
foo.cxx:26:5: error: variable ‘val’ might be clobbered by ‘longjmp’ or ‘vfork’ [-Werror=clobbered]
しかし、単純なint型を使用してもOKです。それは、Aの場合、valは上書きされるかもしれない理由
g++ -DUSE_INT -Wextra -Wno-unused-parameter -O3 -Werror -fPIC foo.cxx
誰かが私に説明していただけます構造体ですが、int型ではないのですか?コード内のコメントに示されているように、構造体を使ってコンパイルを成功させる他の方法についての洞察はありますか?あるいはこれはコンパイラのバグを指していますか?
洞察とコメントは大変ありがとうございます。
つかうおそらくレジスタであることに関連している:ここ
はマシンコード(NSFW)です。 –
このバグがあります。https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48968 –
Basileによるコメントに関して、最適化レベルを下げるとどうなりますか?コンパイラが生成するアセンブリコード(または中間コード)を確認しましたか?それはあなたに何が起こっているのかのヒントを与えるかもしれません。 –