gpt4 book ai didi

c++ - 不一致警告 : variable might be clobbered by ‘longjmp’ or ‘vfork’

转载 作者:可可西里 更新时间:2023-11-01 18:38:29 37 4
gpt4 key购买 nike

我基本上确信我遇到了一些 g++ 4.8.3 错误,但我想我会先问这个列表,因为我对 setjmp/longjmp 的经验很少。我已将相关代码简化为以下 foo.cxx:

#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 是可以的:

g++ -DUSE_INT -Wextra -Wno-unused-parameter -O3 -Werror -fPIC foo.cxx

有人可以向我解释为什么如果 val 是一个结构体,它可能会被破坏,但如果它是一个 int,则不会?如代码中的注释中所示,对结构编译成功的其他方法有何见解?或者这是否指向编译器错误?

非常感谢任何见解和评论。

最佳答案

setjmp() 保存当前堆栈。因为它是在 val 声明之前调用的,所以该变量不会在保存的堆栈中。

setjmp() 之后,变量被初始化,如果代码稍后跳回到 setjmp 点,变量将被再次初始化,破坏旧变量。如果存在应在旧实例上调用的非平凡析构函数,则这是未定义的行为 (§18.10/4):

A setjmp/longjmp call pair has undefined behavior if replacing the setjmp and longjmp by catch and throw would invoke any non-trivial destructors for any automatic objects.

可能不会调用旧实例的析构函数。我的猜测是 gcc 不会针对原始类型发出警告,因为它们没有析构函数,但会针对可能存在问题的更复杂类型发出警告。

关于c++ - 不一致警告 : variable might be clobbered by ‘longjmp’ or ‘vfork’ ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27802892/

37 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com