john@genrad.UUCP (John Nelson) (12/13/83)
I believe that the easiest way to get around the problem is to use a typedef: typedef int (*FUNCTION)(); then you can declare the function returning a pointer to function as: FUNCTION getroutine(name, table) This SHOULD work with all K&R C compilers
bradn@hammer.UUCP (Brad Needham) (12/14/83)
I think your confusion comes from the two ways of declaring a function: 1) with other declarations 2) with the function definition (i.e. the code for the function). Formal parameters do not appear when you declare a function separately from its definition, e.g. int *a(); vs int *a(x) int x; { ... } If you want a function returning a pointer to a function returning an int, you can say it two ways: 1) as a declaration: int (*getroutine())(); 2) or as a declaration and definition: int (*getroutine(name,table))() char *name; struct atable *table; { ... } Because the declaration of functions is so confusing, Graham Ross of Tektronix, MDP wrote a program to convert between English and C declarations. He posted it to net.sources quite a while ago, but I'm sure he can get a copy to you. He is tektronix!tekmdp!grahamr. Brad Needham Tektronix, ECS. ..decvax!tektronix!tekecs!bradn
stevesu@azure.UUCP (Steve Summit) (12/14/83)
Thanks to those who responded. I now know that the correct declaration is int (*getroutine(name,table))() and not the int (*getroutine))((name,table) that I had been trying to use. The astonishing thing is that the pdp11 compilers I have used (2.8bsd, V7, and sysIII based) accept either declaration and generate identical (working) code. Steve Summit tektronix!tekmdp!stevesu
garys@bunkerb.UUCP (Gary Samuelson) (12/14/83)
In reply to Steve Summit, who wanted a function returning a pointer to a function returning an integer: I tried to write this reply in the same style as your request, but I guess I don't speak King James English well enough. Will Today's English suffice :-) ? Using a typedef divides the declaration into bite-sized pieces, which the compiler can swallow. The following program, which I have compiled and run on our VAX (4.1BSD), contains such a function. Simply tear along the dotted line. Gary Samuelson decvax!ittvax!bunker!bunkerb!garys ------------------------------------------------- /* * a couple of functions which return integers */ int g( x ) int x; { return( x + x ); } int h( x ) int x; { return( x * x ); } /* * A function which returns a pointer to a function * which returns an integer. */ typedef int (*ifp)() ; ifp f( a ) int a; { if( a == 0 ) return( g ); else return( h ); } main() { printf( "%d\n", ((*f)( 0 )) ( 4 ) ); printf( "%d\n", ((*f)( 1 )) ( 4 ) ); }
stevesu@azure.UUCP (Steve Summit) (12/15/83)
----------- Crud. It's been pointed out that I said that int (*getroutine))((name,table) is, amazingly, acceptable to the pdp11 compilers. That would be pretty amazing. What I meant to say was that int (*getroutine())(name,table) is acceptable as well as int (*getroutine(name,table))() which is correct. Sorry 'bout that. Steve Summit
kissell@flairvax.UUCP (Kevin Kissell) (12/15/83)
To declare a function returning a pointer to a function returning an integer, the construct int (*funcfunc())() is pretty standard. Things get confusing when the parameters are added. Steve's example of the form int (*getroutine())(name, table) does indeed fail under 4.1, but int (*getroutine(name, table))() will work just fine, and is more correct if you think about it. What I can't figure is how the first version worked under 2.8! Kevin D. Kissell Fairchild Research Center Advanced Processor Development uucp:{ucbvax!sun decvax allegra}!decwrl!flairvax!kissell
dmmartindale@watrose.UUCP (Dave Martindale) (12/18/83)
The declaration int (*getroutine(name,table))() declares a function of two arguments which returns a pointer to a function (taking an unknown number of arguments) which returns an integer. At first glance, I would expect that the declaration int (*getroutine())(name,table)) would declare a routine of zero arguments which returns a pointer to a function of two arguments which returns an integer. But in a declaration of a function, you declare only the parameters to that function, not the parameters which would be passed to any function to which this function may return a pointer. So the declaration should read int (*getroutine())() if getroutine takes no arguments, regardless of what sort of arguments the pointed-to function wants. All of the above applies to the actual function definition. In an external declaration, no arguments to any of the functions are specified, and you would use int (*getroutine())(); for both of the cases discussed. IF C were a language in which the types of arguments were checked and type conversion done automatically, you would see declarations like int (*getroutine(name,table))(value,new,old) char *name; struct tab *table; int value; struct entry *new, **old; where the arguments of both getroutine itself and the routine it returns must be declared. But it isn't - you're responsible for getting the number and types of arguments correct yourself. And since you're not even syntactically allowed to put in the "extra" information about the arguments of the returned routine, there isn't anything for lint to check your code against. Caveat programmer. Dave Martindale
gwyn%brl-vld@sri-unix.UUCP (12/18/83)
From: Doug Gwyn (VLD/VMB) <gwyn@brl-vld> This is nearly the first time I've seen PCC do better than the Ritchie C compiler. int (*g())(n,t) {} generates a "syntax error" message in UNIX System V PCC, as it should.