phil@osiris.UUCP (Philip Kos) (04/20/85)
An interesting question came up at work today. A programmer here was wondering how you would declare an array of pointers to functions returning pointers to integers. I've been able to generate code producing a single pointer to a function returning a pointer to an integer, as int *(*fp_ret_ip)(); but I've been unable to get the C compiler to accept an array version of this. Can this be done? I've tried every combination of paren- theses I could think of, but every time the comiler barfed on it. For the record, I'm using a Pyramid 90x running 4.2BSD/ SysV UNIX. Phil Kos The Johns Hopkins Hospital
gwyn@Brl-Vld.ARPA (VLD/VMB) (04/20/85)
> array of pointers to functions returning pointers to integers
int *(*fp[10])();
works just fine on our C compilers; maybe Pyramid has a problem?
phil@osiris.UUCP (Philip Kos) (04/21/85)
Thanks to everyone who sent me answers. I was apparently trying to put the []'s in the wrong place. Next time I'll remember cdecl. For the record, an array of pointers to functions returning type foo is declared as: foo (*whatever[])(); Phil
ark@alice.UUCP (Andrew Koenig) (04/21/85)
> A programmer here was wondering how you would declare an > array of pointers to functions returning pointers to > integers. I've been able to generate code producing a > single pointer to a function returning a pointer to an > integer, as > int *(*fp_ret_ip)(); > but I've been unable to get the C compiler to accept an > array version of this. Declare 'em like you use 'em: int *(*fp_ret_ip[10])(); This works just fine on my compiler; if it doesn't on yours, maybe your compiler is broken.
brooks@lll-crg.ARPA (Eugene D. Brooks III) (04/22/85)
Declaring arrays of pointers to functions returning pointers to what ever is always a pain to get straight. The slickest solution (other than having godlike mental powers) is documented in "C Notes" by Zahn. You use a set of typedefs to get the job done a step at a time. /* First the type that the function returns. */ typedef int *PI; /* PI is a pointer to an int. */ /* Now the function type. */ typedef PI FPI(); /* FPI is a function returning a pointer to an int. */ /* Now pointer to the above function. */ typedef FPI *PFPI; /* PFPI is a pointer to a function returning a pointer to an int. */ Now an array of these pointers is as for any array. PFPI array[10]; /* An array of function pointers of size 10. */ By building up these rather complicated declarations using typedefs the logic of what you are declaring and how to use it is it bit easier to understand. See "C Notes" by Zahn for a longer explanation of the above and the corrections to any possible errors in the preceeding description.
jordan@greipa.UUCP (Jordan K. Hubbard) (04/23/85)
Ditto, I tried int *(fp_ret_ip[])() on my pyramid and it liked it fine. I was too lazy to test it with an aggregate initialization tho, So I can't in all honesty say that's the best way. Only thing I can say is that there seems to be a definate difference in the handling of * and [].. Some v7 compilers I've seen could give a hoot, it's all the same to them. Others will consider the difference significant. For instance: On the last v7 compiler I used, these two statements were equally valid: static char *foo = { "this", "that", "and the", "other thing" }; static char foo[] = { "etc..", "and so", " forth" }; However, a sysIII compiler on a 68K box would only grok the [] decl. I guess a semantic difference would be that in the latter case you were creating a temporarily unbounded array suitable for such an initialization, whereas you were only allocating space for a pointer before. But, as I say, it's semantic because you could also look at the fact that the static array of pointers is going to be in some compiler-reserved global area anyway & you are merely assigning the address (I hesitated to say 'global section', shades of VMS!).. This has been a puzzling question in the past & I have yet to run into it on 4.2 because I haven't done much of that type of coding on the pyramid yet.. I would welcome any flames/feedback or warnings on the subject. Mail is probably best, I'll summarize if necessary. (But HEY, if you want to start another discussion). -- Jordan K. Hubbard @ Genstar Rental Electronics. Palo Alto, CA. {sun, decwrl, dual}!twg!greipa!jordan I'm your private hacker, hacking for money, any old keyboard will do.. - Tina Turing
brahms@spp5.UUCP (Bradley S. Brahms) (03/04/86)
[}{] Is it just the implementation of c on the AT&T 7300 or is it normal for c not to allow arrays of function pointers? I couldn't find any reference to using arrays of function pointers in K&R but it seemed rather straight forward. To get around the problem I ended up defining a structure with a pointer to a function as its only element then making an array of that structure. Either way, it seems that the end result is the same. -- Brad Brahms usenet: {decvax,ucbvax,ihnp4}!trwrb!trwspp!brahms arpa: Brahms@usc-eclc
friesen@psivax.UUCP (Stanley Friesen) (03/05/86)
In article <111@spp5.UUCP> brahms@spp5.UUCP (Bradley S. Brahms) writes: > >Is it just the implementation of c on the AT&T 7300 or is it normal for c >not to allow arrays of function pointers? I couldn't find any reference >to using arrays of function pointers in K&R but it seemed rather straight >forward. It is "just" the "implementation" of on the ATT 7300. In fact it is a *bug* in the ATT 7300 compiler. In 'C' ypu are allowed to do anything that is not explicitly forbidden. You may make arrays of *any* type except arrays of functions. Any compiler that forbids arrays of function pointers is *broken*. In fact this is the only one I have ever heard of that has this "restriction". You should call the vendor (?AT&T) and complain about this bug. -- Sarima (Stanley Friesen) UUCP: {ttidca|ihnp4|sdcrdcf|quad1|nrcvax|bellcore|logico}!psivax!friesen ARPA: ttidca!psivax!friesen@rand-unix.arpa
woody%Juliet.Caltech.Edu@cit-hamlet.ARPA (04/06/86)
I'm confused. How do you specify an array of pointers to functions? Do you do it: int (*foo[])(); or do you do it: int ((*foo)())[]; The reason why I'm asking is that I need to create a static array of pointers to functions, and have it portable; my slightly used brain cells tell me the second one makes sense (after all, a pointer to a function is 'int (*foo)();'; thus, an array of them should be done by adding the '[]' at the end). Yet, the C compiler I'm using wants it the first way and the logic excapes me as to why. Please send all responces directly to me. And please don't flame me; I'm really confused about this point which is (as far as I can tell) not in K&R. - William Woody NET Woody%Romeo@Hamlet.Caltech.Edu USNAIL 1-54 Lloyd, Caltech / Pasadena, CA 91126
dan@BBN-PROPHET.ARPA (04/07/86)
Re array of pointers to functions: the way I think of it is that C declarations must be read "from the inside out". Start with the identifier itself, and work your way out from the tightest-binding declaration operator to the loosest. The first declaration operator you hit gives you the fundamental type of the object. So, given a declaration containing ... (*x) ... No matter what is surrounding the "(*x)", x is a pointer. Always. Never an array, function, etc., though what it points to may involve these. On the other hand, given ... (x[5]) ... X is definitely an array of 5 (somethings). Maybe pointers, ints, etc. So, to construct an array of pointers, you say (x[]) to get the array, and add the '*' next: (*(x[])) Now it's an array of pointers. What do they point to? Functions: ( (*(x[])) () ) Now all you need to do is specify what the functions return: int ( (*(x[])) () ) And you're done. However, you've left behind a pretty confusing declaration. C typedefs are the perfect way to make things like this easy to understand: typedef int FUNC(); typedef FUNC * FUNC_PTR; FUNC_PTR x[]; Now it's quite clear that x is an array of function pointers. I usually use some variation on this when I have to construct such arrays; it's a lot clearer, even to people like me who have been using C for years. Hope this helps. Dan Franklin
woody%Juliet.Caltech.Edu@cit-hamlet.ARPA (William E. Woody) (04/08/86)
Yesterday I asked which was right: "int (*foo[SIZE])()" or "int ((*foo)())[];" today I got several answers from a few folks out in net-land. Thank you everyone for helping me out in this small point of confusion. Though I have been using C for a couple of years, up until today the section of K&R on declaring variables mystified me; now I know a lot better. The solution I got was to look at declarations from the inside out; thus int foo - An integer int *foo - A pointer to an integer int (*foo)[] - An array of pointers to integers int ((*foo)[])() - An array of pointers to functions returning integers. The whole thing reads from inside out, just as english reads from right to left. Thank you very very much for your time and trouble on this one, net landers! - William Woody NET Woody%Romeo@Hamlet.Caltech.Edu USNAIL 1-54 Lloyd, Caltech / Pasadena, CA 91126
tombre@crin.UUCP (Karl Tombre) (04/08/86)
In article <2398@brl-smoke.ARPA> woody%Juliet.Caltech.Edu@cit-hamlet.ARPA writes: >I'm confused. How do you specify an array of pointers to functions? Do >you do it: > > int (*foo[])(); > >or do you do it: > > int ((*foo)())[]; Your compiler is right of course in taking the first as valid. A you say, this may not be given in K&R, but I found some equivalence rules in another book : "Advanced C: food for the educated palate", by N. Gehani, Computer Science Press (ISBN 0-88175-078-6). You can find out this way: foo : array of pointers to functions returning int => foo[] : pointer to function returning int => *foo[] : function returning int => (*foo[])() : int and thus you have the right syntax. I posted this rather than replying as you are not on UUCP and I have already experienced that mail sent through complex channels does not reach its destination easily. Best regards, -- --- Karl Tombre @ CRIN (Centre de Recherche en Informatique de Nancy) UUCP: ...!vmucnam!crin!tombre or ...!inria!crin!tombre COSAC: crin/tombre POST: Karl Tombre, CRIN, B.P. 239, 54506 VANDOEUVRE CEDEX, France Les plus desesperes sont les chants les plus beaux, Et j'en sais d'immortels qui sont de purs sanglots. Alfred de Musset.
throopw@dg_rtp.UUCP (Wayne Throop) (04/10/86)
> I'm confused. [Is] an array of pointers to functions [declared like this]? > int (*foo[])(); > [or like this?] > int ((*foo)())[]; > [...] > I'm really confused about this point which is (as far as I can tell) not > in K&R. > William Woody Woody%Romeo@Hamlet.Caltech.Edu Actually, it *is* in K&R, though in an unexpected place. Page 90. (Ahem.) [...] the syntax of the declaration for a variable mimics the syntax of expressions in which the variable might appear. Thus, your second example is indirected, then invoked, then subscripted, so it is a pointer to a function returning an array (that is, really a function returning a pointer, though this point is obscure). Your first example is subscripted, then indirected, then invoked, so it is an array of pointers to functions. I always fully parenthesize declarations, so that I'd prefer the first to be "int (*(foo[]))();", just so that the order is less likely to be mistaken. In general, to construct any compound type involving invocation (function returning), indirection (pointer to), or subscription (array of), start from the name, and build outward. For example, let's construct a declaration of an array of pointer to int. foo[] array of *(foo[]) pointer to int *(foo[]); int Or construct a declaration of a function returning pointer to char foo() function returning *(foo()) pointer to char *(foo()); char The construction method is simple. As you read through the description of what you want, just take the previous stuff, parenthesize (to avoid ambiguity), add the new operation to the outside, and top it off with the primitive type. Thus, the example of array of pointer to function returning int becomes foo[] array of *(foo[]) pointer to (*(foo[]))() function returning int (*(foo[]))(); int Note that reading one of these declarations aloud is easy as well. Just start from the name, and read the operators that are applied in turn aloud until you get to the primitive type. "*" is read as "pointer to", "[]" as "array of", and "()" as "function returning", and grouping parenthesis are silent. For example, in this declaration: int *((*(foo[]))()); operations are in this order: 4 2 1 3 so it is an array of pointer to function returning pointer to int. Now, this is one of those recurring topics. I'll agree that C's type declaration syntax is peculiar, and hard to follow at first glance. But I do wonder.... just why does anybody think that "int ((*foo)())[];" is an array of pointer to function? The obscurity of the explanatory K&R passage aside, just what do you folks *do* when you try to construct a declaration in C? This question is *not* rhetorical, nor intended as an insult.... I'd really like to know how folks go about constructing variable and type declarations in C. Please mail me your methods... I'll post a summary if the response warrants it. -- Wayne Throop at Data General, RTP, NC <the-known-world>!mcnc!rti-sel!dg_rtp!throopw
throopw@dg_rtp.UUCP (Wayne Throop) (04/11/86)
AAAAUUUUGGGGHHHH!!!! > Yesterday I asked which was right: > "int (*foo[SIZE])()" or "int ((*foo)())[];" > The solution I got was to look at declarations from the inside out; thus > int foo - An integer > int *foo - A pointer to an integer > int (*foo)[] - An array of pointers to integers > int ((*foo)[])() - An array of pointers to functions > returning integers. Puh*LEEZE* try to be a little more careful, folks. It is probable that the error in the above is a typo, but typo or not, it spreads misinformation. The general principle of declaring from the inside out is correct as stated above, but the last two examples are *INCORRECT*. In particular, (*foo)[] is a pointer to an array, not an array of pointers. Read it from the inside out folks... pointer operation first, then array, hence "pointer to array". Similarly for the last example. It is a pointer to an array of functions returning int, which isn't even legal in C. If the last example had been typechecked before posting, it would have been obvious that it was bogus... lint barfs all over it, saying: array of functions is illegal In addition, a local typechecker gives a somewhat more verbose admonition, like so: arrays cannot contain this type (:FUNCTION_RETURNING (:INT)) As I've said before, puh*LEEZE* be more careful, and (where possible) *TYPECHECK* *POSTED* *EXAMPLES* (with lint at least, and maybe more if you've got more). -- Wayne Throop at Data General, RTP, NC <the-known-world>!mcnc!rti-sel!dg_rtp!throopw
mouse@mcgill-vision.UUCP (der Mouse) (04/12/86)
Well, I tried to mail this, but the percent sign got @ified somewhere along the way, then some later mailer bounced it because of that. Besides, this may help someone else, or at least so I rationalize to myself. > I'm confused. How do you specify an array of pointers to functions? Do > you do it: > int (*foo[])(); This is right. > or do you do it: > int ((*foo)())[]; This specifies a pointer to a function returning an array of ints, if read literally. Since functions cannot return arrays (as current compilers stand), this is nonsense, but that's what it says. > (after all, a pointer to a function is 'int (*foo)();'; thus, an array of > them should be done by adding the '[]' at the end). > Yet, the C compiler I'm using wants it the first way and the logic excapes > me as to why. Here is a technique which I have found helps with complicated declarations; it consists of building the declaration one piece at a time, parenthesizing fully as you go. In this case: Foo should be... foo ...an array of... (foo)[] ...pointers to... *((foo)[]) ...functions returning... (*((foo)[]))() ...int int ((*((foo)[]))()) This is a valid declaration and will work. Some of the parentheses can be stripped out, however: int ((*((foo)[]))()) () binds tighter than the `int', get rid of one pair x x int (*((foo)[]))() () binds tighter than *, keep the next pair x x int (*((foo)[]))() [] binds tighter than *, get rid of the next pair x x int (* (foo)[] )() The innermost pair is totally unnecessary x x int (* foo [] )() and we have the original declaration. If you are not sure which of two things binds tighter, well, it can never hurt to leave the parentheses in, so when in doubt..... I have yet to see a type which will not yield to this technique. Of course, some types do not exist, such as arrays of functions, int foo[](); or functions returning arrays, int foo()[N]; or functions returning functions, int foo()(); though functions returning pointers to functions are OK. int (*foo())(); The declarations can be written, however. You were almost right in talking about throwing [] on the end of the one to get the other; what you need to do is throw the [] on the end of the variable (possibly with parentheses), not the end of the whole declaration. -- der Mouse USA: {ihnp4,decvax,akgua,utzoo,etc}!utcsri!mcgill-vision!mouse philabs!micomvax!musocs!mcgill-vision!mouse Europe: mcvax!decvax!utcsri!mcgill-vision!mouse mcvax!seismo!cmcl2!philabs!micomvax!musocs!mcgill-vision!mouse ARPAnet: utcsri!mcgill-vision!mouse@uw-beaver.arpa Wizard: One who can find and fix bugs in an emergency (such as during a site visit by funding agencies).
cjl@iuvax.UUCP (04/14/86)
> I'm confused. How do you specify an array of pointers to functions? Do > you do it: > int (*foo[])(); > or do you do it: > int ((*foo)())[]; If C enforces postfix notations for all its declarations, the world will be more peaceful. Two of its declarators use postfix notation ( [] and () ), while pointer uses prefix notation ( * ). Confusion about declarator precedence will disappear IF we CHANGE the syntax of pointer declarator to a postfix notation. So when we speak "an array of pointers to functions", we can write down immediately as "int foo [] * ()". To face the reality in the C world, we translate the above back into " (* (foo [])) () ". (Parentheses are used here to avoid the precedence problem.) Remembering the rule that postfix declarators has higher priority than prefix declarators, we can save some of the parentheses as " (* foo []) () ". C.J.Lo UUCP : ...!iuvax!cjl ARPA : cjl@Indiana@CSNet-Relay
rjnoe@riccb.UUCP (Roger J. Noe) (04/15/86)
> just what do you folks *do* when you try to construct a > declaration in C? This question is *not* rhetorical, nor intended as an > insult.... I'd really like to know how folks go about constructing > variable and type declarations in C. Please mail me your methods... > I'll post a summary if the response warrants it. > -- > Wayne Throop at Data General, RTP, NC Tough luck, Wayne, I feel like posting this. See article <662@riccb.UUCP> in net.sources. It's a shell program to convert words to C declarations or casts, somewhat similar to the CDECL seen on the net before but somewhat more portable and easier to modify. Hope it's some use to somebody. I welcome comments and suggestions regarding it. -- "Listen, in order to maintain airspeed velocity a swallow needs to beat its wings forty-three times every second. Right?" Roger Noe ihnp4!riccb!rjnoe
herndon@umn-cs (04/25/86)
If you really want to change the syntax, you should look at Ravi Sethi's article a few years ago on improving the type declarations of the C language. He made a number of relevant suggestions, all of which made good sense to me. Unfortunately, changing this syntax would break so many programs as to be infeasible. Does anyone know where this article is? I seem to recall that it was either in Software Practice & Experience, SIGPLAN Notices, or else it was in a conference proceedings somewhere. Robert Herndon
Unknown@brl-smok (04/25/86)
This message is empty.
davidsen@steinmetz.UUCP (Davidsen) (05/02/86)
Another way to build unusual declarations is by repeated typedefs. The previous posting gave as an example "array of pointers to function returning integer", which is "int (*foo[])()". To build this up: typedef int fri(); /* function returning int */ typedef fri *pfri; /* prointer to function ret. int */ typedef pfri apfri[20]; /* array (size 20) of ... */ Then: apfri foo; /* declares the array */ -- -bill davidsen seismo!rochester!steinmetz!--\ / \ ihnp4! unirot ------------->---> crdos1!davidsen \ / chinet! ---------------------/ (davidsen@ge-crd.ARPA) "Stupidity, like virtue, is its own reward"