我主要確信我自己遇到過一些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:
g++ -DUSE_INT -Wextra -Wno-unused-parameter -O3 -Werror -fPIC foo.cxx
可有人請向我解釋爲什麼,如果它是一個VAL可能會被打一頓結構,但不是如果它是一個int?正如代碼中的註釋所表明的,對於使用該結構進行編譯的其他方法的任何見解?或者這是指向一個編譯器錯誤?
任何見解和意見,非常感謝。
重挫通過'setjmp'等可能與在寄存器之中。 –
可能是這個開放的錯誤https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48968 –
關於Basile的評論,如果降低優化級別會發生什麼?你是否檢查過編譯器生成的程序集(甚至中間)代碼?它可能會給你提示發生了什麼。 –