9

我正在编写需要使用指向 setjmp/sigsetjmp 的指针的多平台代码。通常这就像做一样简单

#include <setjmp.h>
void * sigsetjmp_p = sigsetjmp;

但是,ISO 和 POSIX 声明 setjmp/sigsetjmp 可以定义为宏,在我的 linux 机器中确实是这种情况。以下是摘录/usr/include/setjmp.h

# define sigsetjmp(env, savemask)       __sigsetjmp (env, savemask)

问题是,由于我没有将参数传递给sigsetjmp,因此宏不会扩展,并且sigsetjmplibc 中没有定义普通符号。我希望能够使用一些宏“黑魔法”来提取“__sigsetjmp”名称,但到目前为止我失败了。

另一种选择是 __sigsetjmp直接使用,但这意味着检查每个受支持平台的扩展,我不想这样做(因此这个问题的原因)。

PS:我讨厌宏。

笔记:

我需要这个的原因有点模糊,但为了简化它,假设我想用它执行指针比较。

#include <setjmp.h>
int equals_sigsetjmp(void *p)
{
 void * sigsetjmp_p =  sigsetjmp;
 return p == sigsetjmp_p;
}

编辑:

是的是的。我知道我不应该指望得到一个指针,sigsetjmp因为它在某些平台上甚至可能不是一个函数,但这并不能解决我的问题

在实践中,我所知道的所有平台都将它作为一个函数来实现。

我可以应付这样一个事实,即在几年内,我遇到了一个sigsetjump不适用于某些平台的功能的案例。但是我不想处理的是遍历每个受支持的平台并检查setjmp.h宏定义,这是我现在唯一的选择。

我很欣赏对标准的引用,但我想得到一个实用的答案,而不是纯粹的答案。

4

3 回答 3

2

您不能便携地执行此操作,因为标准明确禁止它(第 7.13 节):

未指定setjmp是使用外部链接声明的宏还是标识符。如果为了访问实际函数(...)而抑制宏定义,则行为未定义。

POSIX 添加到其中

功能sigsetjmp()等同于功能setjmp()

除了一些在这里无关的例外。

至于你的言论

我所知道的所有平台都将它作为一个函数来实现

在 GCC 中,setjmp是内置的,我相信 Clang,所以sigsetjmp. (尽管 C 库也可能有函数版本。)

于 2013-03-06T15:07:17.680 回答
0

怎么样:

void my_sigsetjmp(sigjmp_buf env, int savesigs)
{
    sigsetjmp(env, savesigs);
}

然后使用&my_sigsetjmp的地址

于 2014-06-26T16:59:15.820 回答
-1

对于你所说的你想要的,我会做这样的事情:

#include <setjmp.h>
#ifdef sigsetjmp
#define AVOID_FUNCTION_MACRO /* expand to nothing */
int sigsetjmp AVOID_FUNCTION_MACRO (sigjmp_buf env, int savesigs) {
    log_fatal_error("Can't call sigsetjmp via pointer, its a macro!");
    abort();
}
#endif

这将为您提供一个sigsetjmp可以获取地址的函数,但您实际上不能调用它...

于 2013-03-06T17:05:28.793 回答