Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Macro hell: Platform-independent pointer to setjmp/sigsetjmp

I am writing multiplatform code which needs to use a pointer to setjmp/sigsetjmp. Normally that would be as simple as doing

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

However, ISO and POSIX state that setjmp/sigsetjmp can be defined as a macro, and indeed that is the case in my linux box. Here's an excerpt from /usr/include/setjmp.h:

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

The problem is that, since I am not passing arguments to sigsetjmp, the macro doesn't expand and the plain sigsetjmp symbol is not defined in libc. I was hoping to be able to use some macro "black magic" to extract the "__sigsetjmp" name, but I have failed miserably so far.

Another option would be using __sigsetjmp directly but this would imply checking the expansion for every supported platform, which I don't want to do (hence the reason of this question).

PS: I hate macros.

Note:

The reason for which I need this is a bit obscure, but to simplify it, let's say I want to perform pointer comparisons with it.

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

Edit:

Yes, yes. I know I shouldn't count on getting a pointer to sigsetjmp because it might not even be a function in certain platforms but this doesn't solve my problem.

In practice, all platforms I know of implement it as a function.

I can cope with the fact that, in a few years, I run into a case in which sigsetjump is not a function for certain platform. But what I wouldn't like to cope with is going through every supported platform and check setjmp.h for macro definitions, which is my only option right now.

I appreciate the references to standards but I would like to get a practical answer not a purist one.

like image 637
fons Avatar asked Mar 06 '13 15:03

fons


1 Answers

You can't do this portably, as the standard explicitly forbids it (§7.13):

It is unspecified whether setjmp is a macro or an identifier declared with external linkage. If a macro definition is suppressed in order to access an actual function (...) the behavior is undefined.

To which POSIX adds that

The sigsetjmp() function shall be equivalent to the setjmp() function

with some exceptions that are irrelevant here.

As for your remark

all platforms I know of implement it as a function

In GCC, setjmp is a built-in, and I believe in Clang, so is sigsetjmp. (Though the C library might have a function version as well.)

like image 82
Fred Foo Avatar answered Oct 05 '22 22:10

Fred Foo