Path: utzoo!utgpu!news-server.csri.toronto.edu!rutgers!tut.cis.ohio-state.edu!zaphod.mps.ohio-state.edu!uakari.primate.wisc.edu!aplcen!haven!mimsy!chris From: chris@mimsy.umd.edu (Chris Torek) Newsgroups: comp.lang.c Subject: Re: The right-left rule Keywords: declaration decipher Message-ID: <25587@mimsy.umd.edu> Date: 20 Jul 90 03:44:09 GMT References: <1990Jul16.163612.5344@kfw.COM> <1990Jul16.195111.5976@kfw.COM> <5593@abaa.UUCP> Distribution: na Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742 Lines: 94 In article <5593@abaa.UUCP> korsberg@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@cs.umd.edu Path: uunet!mimsy!chris