gpt4 book ai didi

c - 如何通知编译器 `getcontext` 可以返回多次?

转载 作者:太空宇宙 更新时间:2023-11-03 23:38:24 24 4
gpt4 key购买 nike

getcontext可以返回多次。例如,我画了一个类似于演示的 C 程序 here :

#include <assert.h>
#include <signal.h>
#include <stdio.h>
#include <ucontext.h>

struct communication {
const ucontext_t *return_ctx;
int return_value;
};

static void
test(ucontext_t *thisctx, struct communication *comm)
{
int i = 0;
assert(getcontext(thisctx) == 0);
// getcontext will return 3 times with i having different values

comm->return_value = ++i;
setcontext(comm->return_ctx);
assert(0);
}

int
main(void)
{
ucontext_t mainctx, testctx;
struct communication comm;
char test_stack[SIGSTKSZ];

assert(getcontext(&testctx) == 0);
testctx.uc_stack.ss_sp = test_stack;
testctx.uc_stack.ss_size = sizeof test_stack;
makecontext(&testctx, test, 2,
&testctx, &comm);

for (int i = 0; i < 3; ++i) {
// Rewind test's execution where 'getcontext' returns
comm.return_ctx = &mainctx;
assert(swapcontext(&mainctx, &testctx) == 0);
assert(printf("%d\n", comm.return_value) > 0);
}

return 0;
}

编译运行

$ gcc -std=gnu99 -O3 -o getcontext_test getcontext_test.c
$ ./getcontext_test
1
1
1

没有给出预期的 1 2 3 因为编译器认为 i 在分配给 comm-> 时只能等于 1返回值

我可以通过定义 i volatile 来解决这个问题,但是我想要一个更规范的方法来解决这个问题。

最佳答案

你想要的一个必要(但可能不充分)的要求是制作 i (在 test 函数中;你的标识符的函数之间的名称重复不幸的是,重新询问)volatile。这已经是标准(7.13.2.1 ¶3)中的要求:

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.

对于可能在 setjmp 的连续返回之间被修改的对象,因此您应该(并且应该)用 getcontext 做同样的事情是完全合理的.

由于其他原因,编译器可能需要知道 getcontext 返回不止一次。在 GCC 和兼容的编译器(除 MSVC 之外的大多数编译器)上,您可以使用 __attribute__((__returns_twice__)) 实现此目的。但是,如果需要,声明 getcontext 的 header (或编译器内部结构)应该已经在执行类似的操作。

关于c - 如何通知编译器 `getcontext` 可以返回多次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53101562/

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