[comp.lang.c] Why must setjmp be a macro?

nw@uts.amdahl.com (Neal Weidenhofer) (06/28/90)

In article <5900.267B9A67@puddle.fidonet.org>, cspw.quagga@p0.f4.n494.z5.fidonet.org (cspw quagga) writes:
> ANSI seems to insist that setjmp should be a macro.  (4.6 of the
> report and of the Rationale).  But in various places there are
> references to the setjmp function, and the report also says "It
> is unspecified whether setjmp is a macro or an identifier declared
> with external linkage."
>  
> I looked at three compilers all claiming to be ANSI, and they all
> implemented setjmp as a function, not as a macro.
>  
> Are there any possible differences that a program could discern
> between macro/function implementations in this case (other than
> being able to suppress a macro definition with #undef?)
>  
> Why would ANSI insist that something must be a macro?

One very important thing that you CAN'T do with a macro is put its
address in a pointer and call it through the pointer:

	int (*sj)() = setjmp;

is legal if setjmp is a function, not legal if it is a macro.  Some
architectures and implementations can't handle this kind of indirect
call to setjmp.  As I remember the debate, making setjmp a macro was
to allow these implementations to call themselves ANSI-compliant
because they knew that no strictly conforming program could use this
construct.

> So does the description "macro" actually mean
>   "You are free to implement this as a function, but you may
>    assume no more than a macro?"

In this case it means for the implementation that you can call it a
function if and only if you can handle the above construct.  You might
run this by the three compilers you mentioned above.

> EP Wentworth - Dept. of Computer Science - Rhodes University - Grahamstown.

The opinions expressed above are mine (but I'm willing to share.)

			Regards,
And while the future's          Neal Weidenhofer
	there for anyone        nw@amdahl.uts.amdahl.com
To change, still you            Amdahl Corporation
	know it seems           P. O. Box 3470
It would be easier sometimes    1250 E. Arques Ave. (M/S 316)
	to change the past.     Sunnyvale, CA 94088-3470
				(408)737-5007

dolf@idca.tds.PHILIPS.nl (Dolf Grunbauer) (06/28/90)

In article <96mU02e8b3f201@amdahl.uts.amdahl.com> nw@uts.amdahl.com (Neal Weidenhofer) writes:
<In article <5900.267B9A67@puddle.fidonet.org>, cspw.quagga@p0.f4.n494.z5.fidonet.org (cspw quagga) writes:
<> ANSI seems to insist that setjmp should be a macro.  (4.6 of the
<> report and of the Rationale).  But in various places there are
<> references to the setjmp function, and the report also says "It
<> is unspecified whether setjmp is a macro or an identifier declared
<> with external linkage."
<>  
<> Why would ANSI insist that something must be a macro?
<
<One very important thing that you CAN'T do with a macro is put its
<address in a pointer and call it through the pointer:
<
<	int (*sj)() = setjmp;
<
<is legal if setjmp is a function, not legal if it is a macro.  Some
<architectures and implementations can't handle this kind of indirect
<call to setjmp.

You also cannot use 'setjmp' as a function argument when it is macro (oh well,
this is the same as using it as a pointer).

My question is: why can't some architectures support this ? Sounds very weird
to me as 'setjmp' only stores some registers in a user supplied buffer. Could
you give some examples.

The fact that some 'implementations' can't handle it sounds like a bug in this
implementation IMHO. This could never be a reason why ANSI wanted it to be a
macro.
-- 
Dolf Grunbauer      Tel: +31 55 433233 Internet dolf@idca.tds.philips.nl
Philips Information Systems            UUCP     ...!mcsun!philapd!dolf
Some kind of happiness is measured out in miles

henry@zoo.toronto.edu (Henry Spencer) (06/29/90)

In article <1066@ssp11.idca.tds.philips.nl> dolf@idca.tds.PHILIPS.nl (Dolf Grunbauer) writes:
>[pointers to setjmp]
>My question is: why can't some architectures support this ? Sounds very weird
>to me as 'setjmp' only stores some registers in a user supplied buffer. Could
>you give some examples.
>
>The fact that some 'implementations' can't handle it sounds like a bug in this
>implementation IMHO. This could never be a reason why ANSI wanted it to be a
>macro.

From the Rationale, 4.6:

	setjmp is constrained to be a macro only:  in some implementations
	the information necessary to restore context is only available
	while executing the function making the call to setjmp.

Decrypting that somewhat :-), the problem is that setjmp may need special
handling from the compiler.  You can usually implement setjmp as just an
ordinary function, *if* the compiler is not doing serious optimizing.
If heavy optimization is being done, life is much easier if the compiler
knows that a particular function call is in fact a call to setjmp, so it
can take special precautions.

For example, many compilers want to offer rather stronger guarantees about
the values of local variables after longjmp than ANSI C requires (if for
no other reason, because old code will break otherwise -- X3J11 bungled
this one), and it's very difficult to do that in an optimizing compiler
if setjmp is just another function.  Doing it really right requires saving
and restoring all registers around any calls to other functions in the
function that calls setjmp, but that is much too expensive to do in the
absence of setjmp, so the compiler has to know whether there's a setjmp
there or not.
-- 
"Either NFS must be scrapped or NFS    | Henry Spencer at U of Toronto Zoology
must be changed."      -John Osterhout |  henry@zoo.toronto.edu   utzoo!henry