The right-left rule

Chris Torek chris at mimsy.umd.edu
Fri Jul 20 13:44:09 AEST 1990


In article <5593 at abaa.UUCP> korsberg at abaa.uucp (Ed Korsberg) writes:
>I have a table driven FSM with a state variable (state_variable) which
>points to  one of several state tables ....

>void            (*state1_table[]) () =
>{
>    func_1                /* EVENT 1 */
>    ,func_2               /* EVENT 2 */
>    ,func_3               /* EVENT 3 */
>    ,func_4               /* EVENT 4 */
>};

Two comments: these are actually events 0..3, not 1..4; C syntax allows
trailing commas so that you can write

	void (*tab[])() = {
		f0,
		f1,
		f2,
		f3,
	};

[more tables omitted]
>fsm(event)
>unsigned int event;			/* occurance of EVENT n */
>{
>	void	(*action)();
>	
>	action = state_variable[event]; /* From STATE and EVENT, get action */
>	(*action)();			/* perform action */
>}
>
>****************************************************************************
>Problem is how do you declare a pointer to an array of pointers of functions 
>returning void?

Here is a danger sign: if you ever want a `pointer to an array', think
hard about it.  In particular, think hardest about the N in the array.
Every array is an `array N of T', where N is some constant.  If you do
not know the constant, you probably do not want a pointer to the (entire)
array.  Logically, a pointer to the whole array will do you no good,
because you do not know how many array elements that pointer points to.
You might as well instead point to one array element at a time---if you
can.

This follows from The Rule:

    In any value context, an object of type `array N of T' becomes a
    value of type `pointer to T' whose value is the address of the
    first (0th) element of that array.

Thus, instead of a `pointer to array N of T', you most often want a
`pointer to T'.  (Note, however, that the Rule stops applying once you
have a pointer.  Thus, if you have an `array N of T' where T is, say,
`array 3 of int', you wind up with a `pointer to T', or a `pointer to
array 3 of int'.  This is not an object of type `array N of ...', it is
a value of type `pointer to ...'; it does not get converted again, and
you will need to know the (new) N in the sub-array that is part of `T'.)

In other words, rather than `pointer to array N of T=pointer-to-function-
of-void-returning-void', you probably really want `pointer to T', because
each of your table objects is an `array N of T'.  You could---given N,
or deciding that `N=?'---get a pointer to each one, but you do not *have*
to; it is more convenient to point to the first element of each table.

Thus, you want:

    $ T='pointer to function returning void'
    $ echo "declare state_variable as pointer to $T" | cdecl
    void (**state_table)()
    $

If you really prefer it, you can fix an N (either 4 or ? will suffice
for the example given) and write either

	void (*(*state_table)[4])()	/* N=4 */

or

	void (*(*state_table)[])()	/* N=? */

or either of those using typedef to make them `simpler'.  You will
then have to write, e.g.,

	state_table = &state1_table;

instead of the simpler

	state_table = state1_table;

for the first declaration.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris at cs.umd.edu	Path:	uunet!mimsy!chris



More information about the Comp.lang.c mailing list