[net.lang.c] What is setjmp... Clarification and typedef gripe

nazgul@apollo.uucp (Kee Hinckley) (10/01/84)

...
Gary Moss <decvax!ucbvax!moss@Brl-Vld.ARPA> quite rightly pointed
out that one should never declare the jump buffer as being some
explicit size, but should instead use the typedef "jmp_buf" sitting in:

            /usr/include/setjmp.h

This way you'll avoid the machine dependance problem.

I agree with this whole-heartedly, the only thing that bugs me is
the way typedef works, which is essentially as a #define.  For
example:
-----------------------------------------------------------------------
#include <stdio.h>
#include <setjmp.h>

main()
{
    jmp_buf foo, *tmp;

    tmp = &foo;
}
$ cc foo

 (0008)     tmp = &foo;
******** Line 8: Warning:  Illegal pointer combination: incompatible types.
No errors, 1 warning, C Compiler, Rev 2.40
-------------------------------------------------------------------------
The error message may differ on your machine, but most compilers do at
least give some warning.  The way around it:
            tmp = (jmp_buf *) &foo;
works, but is rather frustrating.

The whole point of a typedef (in my mind at least) is to create a
level of abstraction that alleviates the need to learn what the machine/
compiler architecture actually looks like.  To a certain degree typedef
seems to succeed at this, but then it all falls apart.  Any thoughts?

                                            -kee

keesan@bbncca.ARPA (Morris Keesan) (10/03/84)

--------------------------------------

> From: nazgul@apollo.uucp (Kee Hinckley)
> Date: Mon, 1-Oct-84 14:39:17 EDT
> 
> I agree with this whole-heartedly, the only thing that bugs me is
> the way typedef works, which is essentially as a #define.  For
> example:
> -----------------------------------------------------------------------
> #include <stdio.h>
> #include <setjmp.h>
> 
> main()
> {
>     jmp_buf foo, *tmp;
> 
>     tmp = &foo;
> }
> $ cc foo
> 
>  (0008)     tmp = &foo;
> ******** Line 8: Warning:  Illegal pointer combination: incompatible types.
> No errors, 1 warning, C Compiler, Rev 2.40
> -------------------------------------------------------------------------
> The error message may differ on your machine, but most compilers do at
> least give some warning.  The way around it:
>             tmp = (jmp_buf *) &foo;
> works, but is rather frustrating.
> 
> The whole point of a typedef (in my mind at least) is to create a
> level of abstraction that alleviates the need to learn what the machine/
> compiler architecture actually looks like.  To a certain degree typedef
> seems to succeed at this, but then it all falls apart.  Any thoughts?
> 

    "setjmp foo, *tmp; tmp = &foo;" is accepted with no complaints by my C
compiler (based on the Dennis Ritchie V7 PDP11 "cc"), as it should be, because
"tmp" and "&foo" have exactly the same (defined) type.  Either your C compiler
has a bug in this respect, or your <setjmp.h> is #defining jmp_buf, instead of
typedefing it.  The thing to do is not gripe about the language, but gripe to
whomever maintains your compiler, to get this bug fixed.
-- 
			    Morris M. Keesan
			    {decvax,linus,ihnp4,wivax,wjh12,ima}!bbncca!keesan
			    keesan @ BBN-UNIX.ARPA

henry@utzoo.UUCP (Henry Spencer) (10/04/84)

>>     jmp_buf foo, *tmp;
>> 	...
>>     tmp = &foo;
>> $ cc foo
>> 
>>  (0008)     tmp = &foo;
>> ******** Line 8: Warning:  Illegal pointer combination: incompatible types.

>     "setjmp foo, *tmp; tmp = &foo;" is accepted with no complaints by my C
> compiler (based on the Ritchie V7 PDP11 "cc"), as it should be, because
> "tmp" and "&foo" have exactly the same (defined) type...

The problem, alas, goes deeper, and the Ritchie compiler is covering it up
rather than solving it.  The *real* problem is that many implementations
typedef jmp_buf as an array, and &array is not a legal use of &.  The old
Ritchie compiler lets you get away with it, but more recent ones don't.
I'm not sure just when &array was officially declared illegal; a quick
glance at K&R doesn't find a statement to that effect, but there definitely
is one in the recent ANSI draft.  And pcc, even the old V7 one, does object.

Note that casts don't really solve the problem; &array is *illegal*, and
a strict compiler will reject it completely.

This is a place where typedef isn't as opaque as it should be, alas.  If
jmp_buf is a struct, you must write "tmp = &foo;", whereas if it's an
array you must write "tmp = foo;".  Not good.

Probably the best solution is to lean on your implementor to typedef
jmp_buf as a struct instead of an array; that's probably a better way
to do things all around.
-- 
				Henry Spencer @ U of Toronto Zoology
				{allegra,ihnp4,linus,decvax}!utzoo!henry

bsa@ncoast.UUCP (Brandon Allbery) (10/04/84)

> Article <>
> From: nazgul@apollo.uucp (Kee Hinckley)

> Gary Moss <decvax!ucbvax!moss@Brl-Vld.ARPA> quite rightly pointed
> out that one ... should instead use the typedef "jmp_buf" sitting in:
> 
>             /usr/include/setjmp.h
> 
> I agree with this whole-heartedly, the only thing that bugs me is
> the way typedef works, which is essentially as a #define.  For
> example:
> -----------------------------------------------------------------------
> #include <stdio.h>
> #include <setjmp.h>
> 
> main()
> {
>     jmp_buf foo, *tmp;
> 
>     tmp = &foo;
> }
> $ cc foo
> 
>  (0008)     tmp = &foo;
> ******** Line 8: Warning:  Illegal pointer combination: incompatible types.
> No errors, 1 warning, C Compiler, Rev 2.40
> -------------------------------------------------------------------------
> The error message may differ on your machine, but most compilers do at
> least give some warning.  The way around it:
>             tmp = (jmp_buf *) &foo;
> works, but is rather frustrating.
> 
> The whole point of a typedef (in my mind at least) is to create a
> level of abstraction that alleviates the need to learn what the machine/
> compiler architecture actually looks like.  To a certain degree typedef
> seems to succeed at this, but then it all falls apart.  Any thoughts?

Yup.  I think you may have found a compiler bug.  Here on our humble
Xenix machine, I get:
-----------------------------------------
% cat jb.c
#include <setjmp.h>
main() {jmp_buf foo, *tmp; tmp = &foo;}
% cc jb.c -o foobar # a.out is in use
"jb.c", line 2: warning: & before array or function: ignored
"jb.c", line 2: warning: illegal pointer combination, op =
%
-----------------------------------------
Typedef can't help it -- as long as jmp_buf is an array, you get this.
Either we find a way to make it a struct, or we put up with it.  But
why doesn't your compiler report the *real* problem?  (Or is it one?)

--bsa

thomas@utah-gr.UUCP (Spencer W. Thomas) (10/05/84)

>> From: nazgul@apollo.uucp (Kee Hinckley)
>> Date: Mon, 1-Oct-84 14:39:17 EDT
>> 
>> I agree with this whole-heartedly, the only thing that bugs me is
>> the way typedef works, which is essentially as a #define.  For
>> example:
>> -----------------------------------------------------------------------
>> #include <stdio.h>
>> #include <setjmp.h>
>> 
>> main()
>> {
>>     jmp_buf foo, *tmp;
>> 
>>     tmp = &foo;
>> }
>> $ cc foo
>> 
>>  (0008)     tmp = &foo;
>> ******** Line 8: Warning:  Illegal pointer combination: incompatible types.
>> No errors, 1 warning, C Compiler, Rev 2.40
>> -------------------------------------------------------------------------
>> The error message may differ on your machine, but most compilers do at
>> least give some warning.  The way around it:
>>             tmp = (jmp_buf *) &foo;
>> works, but is rather frustrating.
>> 
>> The whole point of a typedef (in my mind at least) is to create a
>> level of abstraction that alleviates the need to learn what the machine/
>> compiler architecture actually looks like.  To a certain degree typedef
>> seems to succeed at this, but then it all falls apart.  Any thoughts?
>> 

I tried this on our apollo C compiler (the obvious one, given the return
address), and discovered that it complains (as above) about typedefs
for which the underlying type is an array, but not for structs or
"primitive" types (such as int).  On our Vax, similar code gives the
output
  "tst.c", line 7: warning: & before array or function: ignored
  "tst.c", line 7: warning: illegal pointer combination
  "tst.c", line 8: warning: illegal pointer combination
(line 7 said tmp = &foo, and line 8 said tmp = foo).  The problem seems
to be the underlying array type.

=S