[comp.lang.c] Portable uses of jmpbuf's

wsmith@m.cs.uiuc.edu (10/11/88)

How do you portably pass a jmpbuf as a parameter to a C function?

Some machines define a jmpbuf to be struct { stuff } , while
others define a jmpbuf to be an array.  In one case, an & is required, 
while in the other case it is not.

My best solution was to define my own structure with one field of a 
jmpbuf and then always take the address.

Is there a better way?

Bill Smith
uiucdcs!wsmith
wsmith@cs.uiuc.edu

wsmith@m.cs.uiuc.edu (10/12/88)

>/* ---------- "Portable uses of jmpbuf's" ---------- */
>How do you portably pass a jmpbuf as a parameter to a C function?
>
>Some machines define a jmpbuf to be struct { stuff } , while
>others define a jmpbuf to be an array.  In one case, an & is required, 
>while in the other case it is not.
>
>My best solution was to define my own structure with one field of a 
>jmpbuf and then always take the address.
>
>Is there a better way?

Here is a more detailed description of the problem:

If I have a function that I want to pass the address of a jmpbuf to it,
with "typedef struct {} jmpbuf;", the call to the function will be
"function(&a_jmpbuf);" and the prototype ala Microsoft C will be 
"function( jmpbuf * a );"

With "typedef int jmpbuf[10];", the call to the function will be
"function(a_jmpbuf);" and the prototype will be "function( jmpbuf a );"
because the array gets converted into a pointer to its first element when
I make the call.  If I try to make the prototype "function( jmpbuf * a) ;",
the call will no longer match even if make the call be the same as with
the struct version of jmpbuf.

I have heard that one fix is to wait for an ANSI compatible compiler which
will allow "function(&a_jmpbuf);" and "function(jmpbuf * a);" in either case.

Bill Smith	uiucdcs!wsmith		wsmith@cs.uiuc.edu

gwyn@smoke.ARPA (Doug Gwyn ) (10/12/88)

In article <4700022@m.cs.uiuc.edu> wsmith@m.cs.uiuc.edu writes:
>Some machines define a jmpbuf to be struct { stuff } , while
>others define a jmpbuf to be an array.

It's supposed to be an array, since the address of the buffer
is fed to the setjmp/longjmp routines by name and only an array
works right in that context.

Your trick of wrapping it in a structure is okay so long as
you make sure it is the jmpbuf member of the structure you
feed to setjmp/longjmp, not the (address of) the structure.

ron@ron.rutgers.edu (Ron Natalie) (10/12/88)

An extra ampersand doesn't hurt an array definition.

-Ron

henry@utzoo.uucp (Henry Spencer) (10/12/88)

In article <4700022@m.cs.uiuc.edu> wsmith@m.cs.uiuc.edu writes:
>Some machines define a jmpbuf to be struct { stuff } , while
>others define a jmpbuf to be an array.  In one case, an & is required, 
>while in the other case it is not.

People who define it to be a struct have goofed.  There has been enough
trouble with this that X3J11 specifically defines it to be an array (of
some unspecified type).  Of course, this isn't a lot of comfort if your
compiler isn't X3J11-conforming yet...
-- 
The meek can have the Earth;    |    Henry Spencer at U of Toronto Zoology
the rest of us have other plans.|uunet!attcan!utzoo!henry henry@zoo.toronto.edu

jas@ernie.Berkeley.EDU (Jim Shankland) (10/13/88)

In article <Oct.12.10.45.20.1988.17816@ron.rutgers.edu> ron@ron.rutgers.edu (Ron Natalie) writes:
>An extra ampersand doesn't hurt an array definition.

In dpANS C, yes (I think -- right?).  As for today's C implementations,
lots of pcc-based compilers gripe at you, but let you get away with
it; and Amdahl's UTS compiler at least used to treat it as a fatal
error.  In other words, your mileage may vary.

-----
Jim Shankland
jas@ernie.berkeley.edu

"I've been walking in a river all my life, and now my feet are wet"

karl@haddock.ima.isc.com (Karl Heuer) (10/13/88)

In article <4700023@m.cs.uiuc.edu> wsmith@m.cs.uiuc.edu writes:
>I have heard that one fix is to wait for an ANSI compatible compiler which
>will allow "function(&a_jmpbuf);" and "function(jmpbuf * a);" in either case.

If you get an ANSI implementation, it will have an ANSI compatible setjmp() as
well, in which case jmp_buf will always be an array type.

In the meantime, I suggest you "fix" any implementation that gets this wrong
by changing <setjmp.h> to use an array type.  (You can always use an array of
size one, which contains the struct.)  If you can't modify <setjmp.h>, then
copy it and always include your modified copy.

ron@ron.rutgers.edu (Ron Natalie) writes:
>An extra ampersand doesn't hurt an array definition.

Yes it does.

Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint

gwyn@smoke.ARPA (Doug Gwyn ) (10/13/88)

In article <Oct.12.10.45.20.1988.17816@ron.rutgers.edu> ron@ron.rutgers.edu (Ron Natalie) writes:
>An extra ampersand doesn't hurt an array definition.

I don't know how one would use an ampersand on an array definition,
but assuming Ron means that (if "a" is of array type) "a" and "&a"
are equivalent, that was only true for certain broken C implementations.
"&a" used to be illegal.  In ANSI C it has a meaning, but not the same
as "a" (different type, for one thing).

john@uw-nsr.UUCP (John Sambrook) (10/15/88)

In article <4700023@m.cs.uiuc.edu> wsmith@m.cs.uiuc.edu writes:
>
>>/* ---------- "Portable uses of jmpbuf's" ---------- */
>>How do you portably pass a jmpbuf as a parameter to a C function?
>>
>>Some machines define a jmpbuf to be struct { stuff } , while
>>others define a jmpbuf to be an array.  In one case, an & is required, 
>>while in the other case it is not.
>>
>>My best solution was to define my own structure with one field of a 
>>jmpbuf and then always take the address.
>>
>>Is there a better way?
>
>Here is a more detailed description of the problem:
>
>If I have a function that I want to pass the address of a jmpbuf to it,
>with "typedef struct {} jmpbuf;", the call to the function will be
>"function(&a_jmpbuf);" and the prototype ala Microsoft C will be 
>"function( jmpbuf * a );"
>
>With "typedef int jmpbuf[10];", the call to the function will be
>"function(a_jmpbuf);" and the prototype will be "function( jmpbuf a );"
>because the array gets converted into a pointer to its first element when
>I make the call.  If I try to make the prototype "function( jmpbuf * a) ;",
>the call will no longer match even if make the call be the same as with
>the struct version of jmpbuf.
>
>I have heard that one fix is to wait for an ANSI compatible compiler which
>will allow "function(&a_jmpbuf);" and "function(jmpbuf * a);" in either case.
>
>Bill Smith	uiucdcs!wsmith		wsmith@cs.uiuc.edu
>

It seems to me that the problem is how to (reliably, portably) take the
address of a jmp_buf.  The prototype for the called function should
always be "function(jmp_buf *a);"

How about the following?

#if JMP_BUFS_ARE_STRUCTS
#define JMP_BUF_ADDR(X)		(&X)
#else
#define JMP_BUF_ADDR(X)		(X)
#endif

Obviously, you would use this code like this:

	function(JMP_BUF_ADDR(my_jmp_buf));

Granted, you have to figure out the truth of JMP_BUFS_ARE_STRUCTS for
each machine, but that may be better than trying to come up with some
"unification" scheme. 


-- 
John Sambrook                        Internet: john@nsr.bioeng.washington.edu
University of Washington RC-05           UUCP: uw-nsr!john
Seattle, Washington  98195               Dial: (206) 548-4386