clark@umn-cs.CS.UMN.EDU (Robert P. Clark) (04/30/89)
How do I cast something to a pointer to a function that returns
an integer? I'm trying to save the old function, so that I can
call my own function and then chain to the original.
One of my (failed) attempts has been
main()
{
int (*f)();
char *foo();
f = ((*int)())foo(); /* foo returns char*, but I know this is */
/* really an address of a function */
}
Bob Clark clark@umn-cs.cs.umn.edu
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~ ~
~ Never underestimate the bandwidth of ~
~ a station wagon - Andrew Tannenbaum ~
~ ~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
mcgrath@paris.Berkeley.EDU (Roland McGrath) (04/30/89)
int (*f)(); char *foo(); f = (int (*)()) foo(); -- Roland McGrath Free Software Foundation, Inc. roland@wheaties.ai.mit.edu, mit-eddie!wheaties.ai.mit.edu!roland Copyright 1989 Roland McGrath, under the GNU General Public License, version 1.
bph@buengc.BU.EDU (Blair P. Houghton) (04/30/89)
In article <12481@umn-cs.CS.UMN.EDU> clark@umn-cs.CS.UMN.EDU (Robert P. Clark) writes: > >main() >{ > int (*f)(); It's alright, so far... > char *foo(); > > > f = ((*int)())foo(); /* foo returns char*, but I know this is */ > /* really an address of a function */ Bad declaration-to-cast conversion... You want merely to remove the identifier when doing a cast, rather that rearranging anything. The declaration int (*f)(); becomes a cast, therefore, by excising the "f" and the ";" and pre-/ap-pending "(" and ")". f = ( int (*)() ) foo(); >} There are programs out there that do it. If you really want to know, by doing f = ((*int)())... You're trying to call a function pointed-to by a thing called 'int' which is a C keyword, and therefore will generate all sorts of syntactical trouble in the situation you've placed it. PLUG ALERT! Andrew Koenig's _C Traps and Pitfalls_ handles this about as well as it can be handled... GO BACK TO YOUR HOMES, THERE'S NOTHING LEFT TO BE BOUGHT, HERE... --Blair "Do I get a free copy of ed. 2, now, huh, Andy, huh, do I do I do I ?? :-)"
ark@alice.UUCP (Andrew Koenig) (04/30/89)
In article <12481@umn-cs.CS.UMN.EDU>, clark@umn-cs.CS.UMN.EDU (Robert P. Clark) writes: > How do I cast something to a pointer to a function that returns > an integer? One of my (failed) attempts has been > main() > { > int (*f)(); > char *foo(); > f = ((*int)())foo(); /* foo returns char*, but I know this is */ > } Best would be to make foo return an appropriate pointer ane avoid type cheating: int (*foo())(); int (*f)(); f = foo(); The declaration of foo here says that if you call foo, dereference the result, and call that, you get an int. The definition of foo would look something like this: int (*foo())() { /* ... */ } Don't be too astonished if your compiler balks at this -- but it is indeed valid C. Next question: how to declare a variable to contain a pointer to a function that returns an integer? If f is such a variable, then to get an integer from it, you dereference it (to get a function from the function pointer) and then call the function. As your example shows, such a declaration looks like this: int (*f)(); Finally, how do you cast a value to the type of f, assuming you still want to? A cast looks a lot like the declaration with parentheses around it, and with the variable removed that was declared. So int(*f)() becomes (int(*)()) and the assignment looks something like this: f = (int(*)()) foo(); Of course, the cast is unnecessary if you get the type of foo right to begin with. [C-T&P, p. 13] -- --Andrew Koenig ark@europa.att.com
geoff@cs.warwick.ac.uk (Geoff Rimmer) (05/01/89)
In article <12481@umn-cs.CS.UMN.EDU> clark@umn-cs.CS.UMN.EDU (Robert P. Clark) writes: > How do I cast something to a pointer to a function that returns > an integer? The way I use is to imagine I am defining a variable x to be a pointer to function returning int. I would use: int (*x)(); To change this into a cast, take out the x, and put the whole lot in parentheses. (int (*)()) Get the cdecl program! It will do all of this for you. Hope this helps. Geoff /---------------------------------------------------------------\ | GEOFF RIMMER - Friend of fax booths, ANSI C, PCBH, | | & MPFC & cdecl | | email : geoff@uk.ac.warwick.emerald | | address : Computer Science Dept, Warwick University, | | Coventry, England. | | PHONE : +44 203 692320 (10 lines) If I'm out please | | leave a message with my secretary. | | FAX : +44 865 726753 | \---------------------------------------------------------------/
byron@pyr.gatech.EDU (Byron A Jeff) (05/01/89)
In article <12481@umn-cs.CS.UMN.EDU> clark@umn-cs.CS.UMN.EDU (Robert P. Clark) writes:
-
-How do I cast something to a pointer to a function that returns
-an integer? I'm trying to save the old function, so that I can
-call my own function and then chain to the original.
-
-
-One of my (failed) attempts has been
-
-
-main()
-{
- int (*f)();
- char *foo();
-
-
- f = ((*int)())foo(); /* foo returns char*, but I know this is */
- /* really an address of a function */
-}
-
-
-
Try this:
f = (int (*)()) foo();
Because of the parens around the * it is interpreted first. It reads
"cast to a pointer to a function that returns int".
A simple rule of thumb I just though of for doing this: Use
exactly the same declaration for the variable you're trying
to cast to but remove the name (and of course put an extra set
of parens around it.)
So int (*f)() becomes (int (*)()). Yes?
Also it's best to make foo return the same type as
f unless there's a real good reason not to (IMHO).
BAJ
-
- Bob Clark clark@umn-cs.cs.umn.edu
--
Another random extraction from the mental bit stream of...
Byron A. Jeff
Georgia Tech, Atlanta GA 30332
Internet: byron@pyr.gatech.edu uucp: ...!gatech!pyr!byron
diamond@diamond.csl.sony.junet (Norman Diamond) (05/02/89)
In article <12481@umn-cs.CS.UMN.EDU>, clark@umn-cs.CS.UMN.EDU (Robert P. Clark) writes: >> How do I cast something to a pointer to a function that returns >> an integer? In article <9266@alice.UUCP> ark@alice.UUCP (Andrew Koenig) writes: >Best would be to make foo return an appropriate pointer ane >avoid type cheating: > > int (*foo())(); > int (*f)(); > > f = foo(); > >The declaration of foo here says that if you call foo, dereference the >result, and call that, you get an int. The definition of foo would >look something like this: > > int (*foo())() > { > /* ... */ > } > >Don't be too astonished if your compiler balks at this -- but >it is indeed valid C. Mr. Koenig's answers are 100% correct. However, the use of typedef might solve the problem of broken compilers, and maybe even the problem of broken co-workers who have to read your code: typedef int purpose_of_f_t(); typedef purpose_of_f_t *purpose_of_f_ptr_t; typedef purpose_of_f_ptr_t purpose_of_foo_t(); purpose_of_foo_t foo; purpose_of_f_ptr_t f_ptr; int my_int; /* ... */ f_ptr = foo(); /* ... */ my_int = (*f_ptr)(); purpose_of_foo_t foo() { /* ... */ } Norman Diamond, Sony Computer Science Lab (diamond%csl.sony.jp@relay.cs.net) The above opinions are my own. | Why are programmers criticized for If they're also your opinions, | re-inventing the wheel, when car you're infringing my copyright. | manufacturers are praised for it?