Path: utzoo!utgpu!news-server.csri.toronto.edu!bonnie.concordia.ca!uunet!sequent!ogicse!intelhf!ichips!iWarp.intel.com!inews!pima!bhoughto From: bhoughto@pima.intel.com (Blair P. Houghton) Newsgroups: comp.unix.wizards Subject: Re: help with a 'C' problemR Message-ID: <4825@inews.intel.com> Date: 24 Jun 91 06:02:33 GMT References: <1991Jun17.131027.8700@bnlux1.bnl.gov> <1991Jun23.235734.11392@chinacat.unicom.com> Sender: news@inews.intel.com Organization: Intel Corp, Chandler, AZ Lines: 103 In article <1991Jun23.235734.11392@chinacat.unicom.com> woody@chinacat.unicom.com (Woody Baker @ Eagle Signal) writes: >struct FILE > { > ... > struct fileops > { > int (*fread_c)(); /* read a character routine */ > int (*fwrite_c)(); /* write a character routine */ > int (*unkn)(); > ... > } *f_ops; > }; >and a pointer to it >struct FILE *fp; >how would one go about the following? > 1. calling the functions f_ops[0], i.e. the > file read function. Like so: int i; /* integer to catch return value */ i = (fp->f_ops->fread_c)(); The `()' operator has unspecified precedence wrt the `->' operator, hence the parentheses around the calling expression. Note: This assumes you've assigned `fp->f_ops' to point to an existing `struct fileops' object (the declaration above only declares what a `struct fileops' is, it doesn't create one) and set each pointer to point to an elsewhere-defined function. > 2. Reading the address of the function fread_c from the FILE struct `fread_c' is the identifier of a member of the struct, not the name of a function. The value stored in `fp->f_ops->fread_c' is the address of the function. If you want the address of the structure member `fread_c': int (**addr)(); /* addr is ptr to ptr to funct returning int */ addr = &(fp->f_ops->fread_c); /* parentheses are optional here */ > 3. Altering the address of the function fread_c from the FILE struct. Say you've defined a function named `actual_function' like this: int actual_function ( ... ) { /* code that (at the least) causes return of an int */ } And the declaration of `actual_function' is in scope (i.e., using an `extern' declaration (possibly a prototype), or the function-definition itself, earlier in the file); then you'd assign its address to the structure like this: fp->f_ops->fread_c = actual_function; /* sort of like an array name */ or fp->f_ops->fread_c = &actual_function; /* redundant addressof */ >in 68000 code, I am trying to generate code that is equivalent to the >following fragment Questionable move. If you want specific object code, you should code in assembler. That said, this might just work (especially if you optimize). >perhaps the struct fileops should be better constructed to be an >array? This would gain you nothing, and would cost you since you now have to maintain (at the least) documentation associating array indices with function mnemonics, while the structure member names can be listed in the table of contents. An array of pointers to compatible objects should have the same size and alignment as a structure holding the same number of the same kind of pointers. Also, you may have your structure defined wrongly for this; you seem to want the `FILE' structure to contain all of the pointers to functions, rather than point to the `struct fileops' that contains the pointers. To do so, declare `f_ops' without the asterisk, then refer to `fread_c' like so (using the examples above): i = (fp->f_ops.fread_c)(); /* call */ fp->f_ops.fread_c = actual_function; /* assignment */ addr = &(fp->f_ops.fread_c); /* address of struct member */ *addr = actual_function; /* alternative assignment */ i = (*addr)(); /* alternative call */ >Please reply via e-mail, as my time is rather limited (60 min/day) >on my usenet node, and I don't have time to comb through the 'C' newsgroup. Oh, great. Now you tell me... --Blair "Damn it. I'm posting, anyway."