宏地狱:与setjmp / sigsetjmp无关的平台指针

时间:2013-03-06 15:03:49

标签: c macros posix iso setjmp

我正在编写多平台代码,需要使用指向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,因此宏不会扩展,并且在libc中未定义普通sigsetjmp符号。我希望能够使用一些宏“黑魔法”来提取“__sigsetjmp”名称,但到目前为止我已经失败了。

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

PS:我讨厌宏。

注意:

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

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

修改

是的,是的。我知道我不应该指望sigsetjmp指向它,因为它在某些平台上可能不是一个功能,但这不能解决我的问题

在实践中,我所知道的所有平台都将其作为一种功能实现。

我可以应对这样一个事实,即在几年内,我遇到sigsetjump不是某个平台的功能的情况。但我不想处理的是通过每个支持的平台并检查setjmp.h宏定义,这是我现在唯一的选择。

我很欣赏对标准的引用,但我希望得到一个实际的答案,而不是 purist

3 个答案:

答案 0 :(得分:2)

你不能这样做,因为标准明确禁止它(§7.13):

  

未指定setjmp是宏还是使用外部声明的标识符   连锁。 如果为了访问实际功能而禁止宏定义(...),则行为未定义。

POSIX添加了哪个

  

sigsetjmp()函数与<{1}}函数的等效

有一些与此无关的例外情况。

至于你的评论

  

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

在GCC中,setjmp()是内置的,我相信Clang,setjmp也是如此。 (虽然C库也可能有一个函数版本。)

答案 1 :(得分:0)

怎么样:

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

然后使用&amp; my_sigsetjmp

的地址

答案 2 :(得分:-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功能,您可以获取该地址,但您实际上无法将其称为...