gpt4 book ai didi

c++ - 带有 setjmp 的 C++ 对象上的警告 "might be clobbered"

转载 作者:可可西里 更新时间:2023-11-01 17:03:18 24 4
gpt4 key购买 nike

#include <setjmp.h>#include <vector>int main(int argc, char**) { std::vector<int> foo(argc); jmp_buf env; if (setjmp(env)) return 1;}

使用 GCC 4.4.1 g++ test.cc -Wextra -O1 编译以上代码,给出了这个令人困惑的警告:

/usr/include/c++/4.4/bits/stl_vector.h: In function ‘int main(int, char**)’:/usr/include/c++/4.4/bits/stl_vector.h:1035: warning: variable ‘__first’ might be clobbered by ‘longjmp’ or ‘vfork’

STL_vector.h 的第 1035 行是我在构造 foo 时调用的 vector(n, value) 构造函数使用的辅助函数。如果编译器可以计算出参数值(例如,它是一个数字文字),警告就会消失,所以我在这个测试用例中使用 argc,因为编译器无法确定它的值。

我猜这个警告可能是因为编译器优化了 vector 构造,所以它实际上发生在 setjmp 着陆点之后(当构造函数参数取决于函数的参数时,这里似乎就是这种情况)。

我怎样才能避免这个问题,最好是不必将 setjmp 部分分解为另一个函数?

不使用 setjmp 不是一个选项,因为我受困于一堆需要使用它来处理错误的 C 库。

最佳答案

规则是调用 setjmp 的堆栈帧中的任何非 volatile 、非静态局部变量可能会被对 longjmp 的调用破坏。处理它的最简单方法是确保您调用 setjmp 的框架不包含您关心的任何此类变量。这通常可以通过将 setjmp 本身放入一个函数中并传递对在另一个不调用 setjmp 的函数中声明的事物的引用来完成:

#include <setjmp.h>
#include <vector>

int wrap_libcall(std::vector<int> &foo)
{
jmp_buf env;
// no other local vars
if (setjmp(env)) return 1;
// do stuff with your library that might call longjmp
return 0;
}

int main(int argc, char**) {
std::vector<int> foo(argc);
return wrap_libcall(foo);
}

另请注意,在此上下文中,破坏 实际上仅意味着重置为调用 setjmp 时的值。因此,如果在修改本地后永远无法调用 longjmp,您也可以。

编辑

setjmp 上 C99 规范的确切引用是:

All accessible objects have values, and all other components of the abstract machine have state, as of the time the longjmp function was called, except that the values of objects of automatic storage duration that are local to the function containing the invocation of the corresponding setjmp macro that do not have volatile-qualified type and have been changed between the setjmp invocation and longjmp call are indeterminate.

关于c++ - 带有 setjmp 的 C++ 对象上的警告 "might be clobbered",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2024933/

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