我正在编写多平台代码,需要使用指向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 。
答案 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
功能,您可以获取该地址,但您实际上无法将其称为...