我的问题是关于局部变量的setjmp/longjmp的行为。
示例代码:
jmp_buf env;
void abc()
{
int error;
...
if(error)
longjmp(env);
}
void xyz() {
int v1; // non-volatile; changed between setjmp and longjmp
int v2; // non-volatile; not changed between setjmp and longjmp
volatile int v3; // volatile; changed between setjmp and longjmp
volatile int v4; // volatile; not changed between setjmp and longjmp
...
if(setjmp(env)) {
// error handling
...
return;
}
v1++; // change v1
v3++; // change v3
abc();
}
int main(...) {
xyz();
}setjmp/longjmp的文档说:
“所有可访问对象的值在调用longjmp()时都有,但具有自动存储持续时间的对象的值是不确定的,这些对象是包含相应setjmp()调用的函数的本地值,这些对象不具有易失性限定类型,并且在setjmp()调用和longjmp()调用之间进行更改。”
我看到以下两种可能的解释:
intepretation1:
将恢复局部变量,但两个变量都还原的变量除外。
和
intepretation2:
恢复局部变量,但
的。
根据interpretation1的说法,只有v1是未定义的。定义了v2,v3,v4。根据interpretation2,在longjmp之后只定义了v4。v1,v2,v3是未定义的。
哪一个是对的?
顺便说一句:我需要一个对所有编译器都有效的通用(“可移植”)答案,也就是说,用一个特定的编译器进行测试是没有帮助的。
发布于 2009-09-08 11:29:26
解释1是正确的。如果解释2是有意的,那么原文将使用“或”而不是"and“。
发布于 2009-09-08 11:29:38
setjmp/longjmp是通过第一次传递时保存寄存器(包括堆栈和代码指针等),并在跳转时恢复寄存器来实现的。
非“易失性”的自动(也称为“本地”,堆栈分配)变量可以存储在寄存器中而不是堆栈上。
在这种情况下,longjmp将在首次调用setjmp()时将这些寄存器变量恢复到它们的值。
此外,特别聪明的编译器可能会避免从另一个变量的状态推断变量,并根据需要计算它们。
但是,如果变量是自动的,但没有分配寄存器,则可以通过setjmp和longjmp之间的代码对其进行更改。
易失性是显式地告诉编译器不要将变量存储在寄存器中。
因此,除非显式地说变量是易失性的,否则如果在setjmp/longjmp之间更改变量,它的值将取决于编译器所做的选择,因此不应该依赖(‘不确定性’)。
https://stackoverflow.com/questions/1393443
复制相似问题