I have [a pointer to struct containing a jmp_buf named "state", and also]
int *state_pointer; ...
state_pointer = (int *) &pcb_pointer->state;
state_pointer point to the address of state in the pcb struct.
What confuses me is that state_pointer is an integer pointer while state has
type jmp_buf. How can an integer pointer point to a variable with type
jmp_buf??
It cannot. Unless perhaps it can; see below. But the cast -- the
thing in parentheses -- tells the compiler: "shut up about this
code that is probably wrong, because I, the programmer, know much
better than you and I want to do it anyway."
As a general rule, pointer casts in C mean that whoever wrote the
code was either very smart, or rather careless.
Most C code
should be cast-free. There are some exceptions, and casts from
int to double (or vice versa), for instance, are pretty mild and
minor. It is pointer casts that get people into trouble. If you
can write the code without a cast, and compile it without complaint
from the compiler, you will usually be better off than if you use
a cast and shut the compiler up even if it is right and your code
is wrong after all.
Now, if we take out the cast, *and* take out the unary "&" operator:
state_pointer = pcb_pointer->state;
and if the code still compiles quietly, then we have learned
something about the implementation in question. We know -- from
the C standard, which says so -- that "jmp_buf" is a typedef for
an array type. We do not know what the array type is, and it may
(and probably does) change from one compiler to the next. But it
could well be a typedef for "array N of int", for some constant N,
and in fact this turns out to be fairly common. If you have a text
<setjmp.h> that you can read, you might peek at it and find:
typedef int jmp_buf[2];
on some machine, and:
typedef int jmp_buf[11];
on another. And of course, we all know The Rule about arrays and
pointers in C by now (see
http://web.torek.net/torek/c/pa.html),
so:
int *p;
int arr[N];
...
p = arr;
is quite OK (setting p to &arr[0]). If jmp_buf is a typedef for
"array N of int", then -- regardless of the constant N -- the
assignment to "int *" is OK.
Of course, the moment you change compilers and/or machines, you
may find the code is no longer OK, because now perhaps jmp_buf
is a typedef of the form:
typedef struct __jmp_buf {
short __jb_rX;
long __jb_rY;
char *__jb_rZ;
} jmp_buf[1];
So it is not a good idea to use "int *" to point to a jmp_buf,
even if it happens to work on the machine at hand.