macro with optional function calls and return value

C

Capstar

Hi NG,

I have the following struct, macro and functions prototypes:

typedef struct {
jmp_buf __env;
/*other stuff*/
} SAT;

#define smalloc_init(sat_p, size) \
(smalloc_init_(sat_p, size) || ssetjmp_(sat_p,setjmp((sat_p)->__env)))

int smalloc_init_(SAT *sat_p, size_t size);
int ssetjmp_(SAT *sat_p, int sjval);

The idea is that smalloc_init is called from an application.
Then smalloc_init_ is called to initialise sat_p. If that fails it
returns -1, and ssetjmp_ is never called. If it succeeds, it returns 0,
and thus ssetjmp_ is called with setjmp((sat_p)->__env) as one of its
arguments.
ssetjmp_ is basicly a wrapper around setjmp, so if setjmp returns 0, it
will do nothing, otherwise it will clean up some stuff.

I need to do this using a macro because I can't use setjmp inside the
initialisation function because the jmp_buf would be invalid after I
return from that function.

So what I want is to use this stuff like this from the application:

switch(smalloc_init(&s, 4))
{
case -1:
puts("smalloc_init failed");
return 1;

case 0:
break;

default:
puts("smalloc failed");
return 1;
}

This compiles fine, gcc gave me no warnings, and I thought it was OK,
until I compiled it with visual c++. That gave me a warning about the
'||' in the switch, which I possibly mistaken for a '|'.

So I checked and realized this expression would indeed only return 0 or
1. Which is not what I want. So now I'm looking for a portable way of
solving this. I know in gcc I can do something like

#define smalloc_init(sat_p, size) \
({int __ret = smalloc_init_(sat_p, size); \
if(!__ret) __ret = ssetjmp_(sat_p,setjmp((sat_p)->__env)); \
__ret;
})

But that's not portable.I could also chenge ssetjmp_ that it would take
the return value of smalloc_init_(...) aswell as the return value of
setjmp(...). But than there's no guarantee about the order of those two
being called, which might result in a reinitialisation of sat_p on a
return from setjmp via a longjmp.

Are there any ways to solve this issue, preferably without changing the
way smalloc_init is called and used.

Thanks in advance,
Mark
 
C

Capstar

Ok, I solved this one with the following macro:

#define smalloc_init(sat_p, size) \
(smalloc_init_(sat_p, size) ? -1 : \
ssetjmp_(sat_p,setjmp((sat_p)->__env)))

But if smalloc_init_ would also return other values in stead of only 0
and -1, this wouldn't work. So I'm still open for any options that don't
have this restriction.

Mark
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top