tuna@athena.mit.edu (Kirk 'UhOh' Johnson) (05/31/90)
the following bits of grammar are culled from appendix A of K&R (1st ed.): function-declarator: /* page 204 */ declarator ( parameter-list_opt ) declarator: /* page 194 */ identifier ( declarator ) * declarator declarator ( ) declarator [ constant-expression_opt ] so a function "foo" returning a pointer to a function returning an int would be declared as: int (*foo())() { /* body of foo */ } imagine that i'd like "foo" to take one argument, arg, an integer. given the bits of grammar shown above, i would expect use: int (*foo())(arg) int arg; { /* body of foo */ } unfortunately, both pcc and gcc choke upon such a declaration. but if i rearrange things as int (*foo(arg))() int arg; { /* body of foo */ } both compilers generate code which seems to do the right thing, despite the fact that this declaration of "foo" doesn't seem to match the grammar shown in my copy of K&R (1st ed.). anybody have any helpful comments? how should the function-declarator grammar really read? if the problem is that K&R (1st ed.) is out of date, is there a better reference that isn't? although i will try to keep up with comp.lang.c to look for responses to my questions, i'd appreciate it if responses could also be e-mailed so i don't inadvertently miss them. thanks in advance for any help kirk -- ------------------------------------------------------------------------------- kirk johnson `Eat blue dogs tuna@masala.lcs.mit.edu and dig life.'
drh@romeo.cs.duke.edu (D. Richard Hipp) (05/31/90)
To: tuna@athena.mit.edu Subject: Re: function declarator strangeness Newsgroups: comp.lang.c In-Reply-To: <1990May30.173922.11825@athena.mit.edu> Organization: Duke University CS Dept.; Durham, NC Cc: Bcc: In article <1990May30.173922.11825@athena.mit.edu> you write: >the following bits of grammar are culled from appendix A of K&R (1st ed.): > function-declarator: /* page 204 */ > declarator ( parameter-list_opt ) > declarator: /* page 194 */ > identifier > ( declarator ) > * declarator > declarator ( ) >so a function "foo" returning a pointer to a function returning an int >would be declared as: > int (*foo())() >imagine that i'd like "foo" to take one argument, arg, an integer. >given the bits of grammar shown above, i would expect use: > int (*foo())(arg) >unfortunately, both pcc and gcc choke upon such a declaration. but if >i rearrange things as > int (*foo(arg))() >both compilers generate code which seems to do the right thing, >despite the fact that this declaration of "foo" doesn't seem to match >the grammar shown in my copy of K&R (1st ed.). This appears to be a mistake in K&R. My intuition (based on the inside-out rule) told me that PCC and GCC had it right. I went home and checked my (Nov '85 draft of the) ANSI-C standard and it agrees as well. The correct declaration is int (*foo(x))(){ ... } The declaration int (*foo())(x){ ... } is wrong. The inside-out rule is this: To find the English description of the type of an object, start with the objects name, and work toward the outside. Example: the incorrect declaration reads: "foo is function returning pointer to function with argument x returning integer". Such is not what you want. Applying the same inside-out rule to the first declaration yields: "foo is function with argument x returning pointer to function returning integer." That sounds better... Here is the unraveling again, but broken into a table to better show what is happening: ENGLISH C ------------------------------------ ------------------- foo is foo function with argument x returning foo(x) pointer to *foo(x) function returning (*foo(x))() integer int (*foo(x))()