stevesu@azure.UUCP (Steve Summit) (12/13/83)
And it came to pass that I desired to code a function returning a pointer to a function returning an integer, and with good reason, for it was not a hack; and I was distressed, for I was unsure as to what form the incantation should take, but I crossed my fingers, and I did guess, and I did type int (*getroutine())(name, table) for the name of the routine was getroutine, and its arguments were name and table; and I did luck out, for the compiler was pleased, and it did emit code, and the code did run, for this was a lowly 11, running 2.8bsd, and some things were easier then. And the program was good, and it went forth, and multiplied, and it came to pass, that I desired to compile it again, on a vax under 4.1 . And the compiler did puke, and it did shout syntax error, for it did consider my incantation a blasphemy; and not recognizing the declaration of a function, it did consider the rest of my file to be in error as well. And I did repent, for I had used the heathen method of trial and error, and although I had skirted the first trial, I had been eventually judged to be in error. And I sought comfort in the scriptures, and I consulted the Book of Brian and Dennis, as I should have done in the first place, and in chapter 5, on page 116, I did read, that the declarations should be studied with some care, and I did study, with some care; but the example given was merely a pointer to a function, and not the function returning the same, that I desired. And as I studied the example, I did reason that if int *a was the declaration for a pointer to an integer and int *a(x) was the declaration for a function of x returning a pointer to an integer; then if int (*a)() was the declaration for a pointer to a function returning an integer, then surely int (*a)()(x) should be the declaration for a function of x returning a pointer to a function returning an integer, and this did I try, but still was the compiler displeased, and I did reason that perhaps another level of parenthesis might be required, as in (int (*a)())(x) or perhaps ((int)(*a)())(x) and these too did I try, but still was the compiler displeased, and still did it continue to pass numerous judjements on my program, beginning with "syntax error" on the afflicted line, and continuing with others too numerous to mention. And I did realize, that I was again regressing into the accursed method of trial and error, and that along that path surely did not lie salvation, and so now do I beseech you, my brothers and sisters on the net, and fellow supplicants of unix, to guide me if you can, out of my darkness and into the light, that I might declare a function returning a pointer to a function returning an integer, in a way equally blessed under the deities of 2.8 and 4.1 . Steve Summit tektronix!tekmdp!stevesu P.S. And it came to pass, that I recieved many flames, as if directly from the gates of Hell, for the net was not amused, and it did suggest that I should have submitted my beseechment to net.religion, or /dev/null; and if this be the case, then I apologize, but I am in a curious mood today, and ask forgiveness, for I know not what I do.
ark@rabbit.UUCP (12/14/83)
Suppose I want to write a function f that returns a pointer to a
function returning an integer. I first think about how I'm going to
invoke it.
f(x)
is going to be a pointer to a function, so
*f(x)
will be this function itself. Well, since * binds less tightly than
function calls, I must invoke the (secondary) function by saying
(*f(x))()
and this expression is now an integer. If I want to write f, I therefore
say:
inf (*f(x))()
int x;
{
...
}
Works like a charm.
djh@ccivax.UUCP (12/15/83)
The declaration 'int (*ptr)()' defines 'ptr' as a pointer to an integer function. What you want to do is replace 'ptr' with your function definition of 'getroutine(name, table)', thus giving 'int (*(getroutine(name, table)))()' which defines getroutine as a function with two arguements which returns a pointer to an integer function (or function that returns an integer). Note that 'ptr' was replaced by '(getroutine(name, table))'. The enclosing parenthesis are necessary to bind the arguements to getroutine before the * (pointer binding) is applied. Following is a sample program and execution printout. /* * functest.c program to test functions that return pointers * to other functions. */ int a() /* define integer function a */ { printf("In function 'a'\n"); return(1); } int b() /* define integer function b */ { printf("In function 'b'\n"); return(2); } int c() /* define integer function c */ { printf("In function 'c'\n"); return(3); } int (*(func(arg)))() /* define function func which returns */ int arg; /* an integer function pointer */ { switch(arg) { case 1: return(a); case 2: return(b); case 3: return(c); } } main() { int (*ptr)(); /* ptr is pointer to integer function */ ptr = func(3); printf("Returned %d\n",(*ptr)()); ptr = func(1); printf("Returned %d\n",(*ptr)()); /* ptr = func(2); test without intermediate step */ printf("Returned %d\n",(*(func(2)))()); } Sample Execution: In function 'c' Returned 3 In function 'a' Returned 1 In function 'b' Returned 2 Dan Hazekamp Computer Consoles Inc. Rochester N.Y. {siesmo,allegra}!rochester!ccivax!djh
stevens@inuxh.UUCP (12/16/83)
> The declaration 'int (*ptr)()' defines 'ptr' as a pointer to > an integer function. What you want to do is replace 'ptr' with > your function definition of 'getroutine(name, table)', thus > giving 'int (*(getroutine(name, table)))()' which defines > getroutine as a function with two arguements which returns a > pointer to an integer function (or function that returns an > integer). > > Note that 'ptr' was replaced by '(getroutine(name, table))'. > The enclosing parenthesis are necessary to bind the arguements > to getroutine before the * (pointer binding) is applied. No, the parentheses around '(getroutine(name, table))' are not required. function arguments `()' bind more tightly than pointer dereferencing `*'. (K & R, p. 49 [the page my K & R falls open to]). -- Scott Stevens AT&T Consumer Products Laboratories Indianapolis, Indiana UUCP: inuxh!stevens
gwyn%brl-vld@sri-unix.UUCP (12/16/83)
From: Doug Gwyn (VLD/VMB) <gwyn@brl-vld> In C, * binds weaker than func() so parentheses are NOT necessary in *func() if you want to call the function, then dereference the return value.