Dereferencing f-pointers, arrays of f-pointers, pointers to f-pointers
Author |
Message |
Glynn #1 / 3
|
 Dereferencing f-pointers, arrays of f-pointers, pointers to f-pointers
Can someone give me the ANSI rules that explain the correct way to dereference arrays of function pointers, pointers to function pointers, etc? The program below gives different results under two different "ANSI" compilers (gcc & eic). Thanks, Glynne #include <stdio.h> #include <stdlib.h> #include <string.h> /* Prototypes */ typedef void myfunc(int,int); typedef myfunc * pmyfunc; /* Functions */ void funcA(int a, int b) {printf("funcA called\n");} void funcB(int a, int b) {printf("funcB called\n");} int main( int argc, char *argv[] ) { pmyfunc pF= 0; pmyfunc apF[4]= {0}; myfunc *pF2= 0; static myfunc **ppF; /* various ways of assigning pointers */ pF= &funcB; pF2= funcA; apF[0]= funcA; apF[1]= funcB; ppF= apF; /* call the functions directly */ funcA( 1, 1 ); funcB( 1, 1 ); /* Now via pointers */ pF( 1, 1 ); pF2( 1, 1 ); /* These lines show that a function pointer is not the same as a data * pointer. The only way to "dereference" a function pointer is to use () * * Using * does not dereference the pointer, it seems to be a no op. * Using [] does not dereference a function pointer, either. */ (pF)( 1, 1 ); /* OK, calling function via f-pointer */ (*pF)( 1, 1 ); /* OK, * is a noop not a dereference */ /* Assign f-pointers to elements in an array of f-pointers */ pF2= apF[0]; /* matching levels of indirection */ pF2= ppF[0]; /* matching levels of indirection */ pF2= *ppF; /* matching levels of indirection */ #if defined(__GNUC__) printf( "GCC specific stuff\n" ); /* These statements are OK under GCC, but FAIL under EiC */ (***pF)(1, 1); /* ANSI says * is a noop, not a dereference */ (*****ppF)(1, 1); /* .... extends to pointer to f-pointer? */ (*****apF)(1, 1); /* .... extends to array of f-pointers? */ pF2= *****ppF; /* .... extends to pointer assignments?? */ pF2= pF+13; /* pointer arithmetic on f-pointers is legal?? */ #elif defined(_EiC) printf( "EiC specific stuff\n" ); /* These statements are OK under EiC, but FAIL under GCC */ pF[0]( 1, 1 ); /* Using [] to dereference an f-pointer */ apF[1][0]( 1, 1 ); /* Using [][] to dereference array of f-pointers */ #else printf( "non-EiC, non-GCC stuff\n" ); /* These statements FAIL under both EiC and GCC */ pF2= pF[0]; /* mismatched levels of indirection */ #endif /* Now some fun with double indirection */ apF[0]( 1, 1 ); /* Using [] to dereference array of f-pointers */ (*apF)( 1, 1 ); /* Using * to dereference array of f-pointers */ ppF[0]( 1, 1 ); /* Using [] to dereference pointer to f-pointer */ (*ppF)( 1, 1 ); /* Using * to dereference pointer to f-pointer */ (*apF[1])( 1, 1 ); /* Using * for pointer and [] for array */ return(0); Quote: }
|
Fri, 28 Nov 2003 06:41:09 GMT |
|
 |
thinki #2 / 3
|
 Dereferencing f-pointers, arrays of f-pointers, pointers to f-pointers
thank you for not using decimal. of course, you don't have any numbers over 9 so i can't tell.
Quote: >Can someone give me the ANSI rules that explain the correct way to >dereference arrays of function pointers, pointers to function pointers, etc? >The program below gives different results under two different "ANSI" >compilers (gcc & eic). >Thanks, >Glynne >#include <stdio.h> >#include <stdlib.h> >#include <string.h> >/* Prototypes */ >typedef void myfunc(int,int); >typedef myfunc * pmyfunc; >/* Functions */ >void funcA(int a, int b) {printf("funcA called\n");} >void funcB(int a, int b) {printf("funcB called\n");} >int main( int argc, char *argv[] ) >{ > pmyfunc pF= 0; > pmyfunc apF[4]= {0}; > myfunc *pF2= 0; > static myfunc **ppF; > /* various ways of assigning pointers */ > pF= &funcB; > pF2= funcA; > apF[0]= funcA; > apF[1]= funcB; > ppF= apF; > /* call the functions directly */ > funcA( 1, 1 ); > funcB( 1, 1 ); > /* Now via pointers */ > pF( 1, 1 ); > pF2( 1, 1 ); >/* These lines show that a function pointer is not the same as a data > * pointer. The only way to "dereference" a function pointer is to use () > * > * Using * does not dereference the pointer, it seems to be a no op. > * Using [] does not dereference a function pointer, either. > */ > (pF)( 1, 1 ); /* OK, calling function via f-pointer */ > (*pF)( 1, 1 ); /* OK, * is a noop not a dereference */ > /* Assign f-pointers to elements in an array of f-pointers */ > pF2= apF[0]; /* matching levels of indirection */ > pF2= ppF[0]; /* matching levels of indirection */ > pF2= *ppF; /* matching levels of indirection */ >#if defined(__GNUC__) > printf( "GCC specific stuff\n" ); > /* These statements are OK under GCC, but FAIL under EiC */ > (***pF)(1, 1); /* ANSI says * is a noop, not a dereference */ > (*****ppF)(1, 1); /* .... extends to pointer to f-pointer? */ > (*****apF)(1, 1); /* .... extends to array of f-pointers? */ > pF2= *****ppF; /* .... extends to pointer assignments?? */ > pF2= pF+13; /* pointer arithmetic on f-pointers is legal?? */ >#elif defined(_EiC) > printf( "EiC specific stuff\n" ); > /* These statements are OK under EiC, but FAIL under GCC */ > pF[0]( 1, 1 ); /* Using [] to dereference an f-pointer */ > apF[1][0]( 1, 1 ); /* Using [][] to dereference array of f-pointers */ >#else > printf( "non-EiC, non-GCC stuff\n" ); > /* These statements FAIL under both EiC and GCC */ > pF2= pF[0]; /* mismatched levels of indirection */ >#endif > /* Now some fun with double indirection */ > apF[0]( 1, 1 ); /* Using [] to dereference array of f-pointers */ > (*apF)( 1, 1 ); /* Using * to dereference array of f-pointers */ > ppF[0]( 1, 1 ); /* Using [] to dereference pointer to f-pointer */ > (*ppF)( 1, 1 ); /* Using * to dereference pointer to f-pointer */ > (*apF[1])( 1, 1 ); /* Using * for pointer and [] for array */ > return(0); >}
|
Fri, 28 Nov 2003 07:31:43 GMT |
|
 |
Joe Mau #3 / 3
|
 Dereferencing f-pointers, arrays of f-pointers, pointers to f-pointers
Quote:
> Can someone give me the ANSI rules that explain the correct way to > dereference arrays of function pointers, pointers to function pointers, etc? > The program below gives different results under two different "ANSI" > compilers (gcc & eic).
A couple of points. First, any expression that has a function type `F` is converted to type `pointer to F` (pointing to that function), except when it's the operand of the `sizeof` operator or the `&` operator. It follows then that the `()` function call operator takes an operand of type `pointer to F`, since any expression of some function type `F` will be converted to `pointer to F` before being operated on by the function call operator. Second, you cannot perform pointer arithmetic on a function pointer, so trying to apply the `[]` operator (which works by adding an integer to a pointer) to a function pointer is invalid (constraint violation). Also, remember that a function pointer is a regular object, so that a `pointer to a function pointer` is an _object_ pointer (what you call below _data pointer_) and behaves as such, not as a `pointer to function` itself which has different rules than object pointers. Now, lets see: [...] Quote: > typedef void myfunc(int,int); > typedef myfunc * pmyfunc; > /* Functions */ > void funcA(int a, int b) {printf("funcA called\n");} > void funcB(int a, int b) {printf("funcB called\n");} > int main( int argc, char *argv[] ) > { > pmyfunc pF= 0; > pmyfunc apF[4]= {0}; > myfunc *pF2= 0; > static myfunc **ppF;
Note that `ppf` is an object pointer, not a function pointer. [...] Quote: > /* call the functions directly */ > funcA( 1, 1 ); > funcB( 1, 1 );
Actually, these do not "call the functions directly". The identifiers `funcA` and `funcB` are converted to pointers to functions, and the function call operators operate on these, as noted above. Quote: > /* These lines show that a function pointer is not the same as a data > * pointer. The only way to "dereference" a function pointer is to use ()
Not quite. The `()` operator calls the function pointed to by its operand, which is not quite the same as dereferencing the pointer. Quote: > * > * Using * does not dereference the pointer, it seems to be a no op.
Yes, it does, and the resulting type is some function type `F`. However, it is immediately converted back into a `pointer to function` type by the aforementioned rule, so that you can apply the `*` operator to it all over again - which will have the same result - and so on, recursively. Quote: > * Using [] does not dereference a function pointer, either.
Using `[]` on a function pointer is invalid and requires a diagnostic from your compiler. Quote: > */ > (pF)( 1, 1 ); /* OK, calling function via f-pointer */ > (*pF)( 1, 1 ); /* OK, * is a noop not a dereference */
Not quite. It yields a function type, which is converted back into a pointer to function type. [...] Quote: > /* These statements are OK under GCC, but FAIL under EiC */ > (***pF)(1, 1); /* ANSI says * is a noop, not a dereference */
See above. Quote: > (*****ppF)(1, 1); /* .... extends to pointer to f-pointer? */
Since `*ppF` yields a function pointer, it behaves like any other function pointer. Quote: > (*****apF)(1, 1); /* .... extends to array of f-pointers? */
apF is an array, which also has the "converts to pointer" rule (see the FAQ). So apF in the expression above has the same type as ppF. Quote: > pF2= *****ppF; /* .... extends to pointer assignments?? */
The expression above yields a function pointer type, which you assign to pF2. Quote: > pF2= pF+13; /* pointer arithmetic on f-pointers is legal?? */
No. Quote: > /* These statements are OK under EiC, but FAIL under GCC */ > pF[0]( 1, 1 ); /* Using [] to dereference an f-pointer */
This is invalid. Quote: > apF[1][0]( 1, 1 ); /* Using [][] to dereference array of f-pointers */
The first `[]` here operates on an object pointer, the second is invalid. [...] Quote: > /* Now some fun with double indirection */ > apF[0]( 1, 1 ); /* Using [] to dereference array of f-pointers */ > (*apF)( 1, 1 ); /* Using * to dereference array of f-pointers */ > ppF[0]( 1, 1 ); /* Using [] to dereference pointer to f-pointer */ > (*ppF)( 1, 1 ); /* Using * to dereference pointer to f-pointer */
apF and ppF have the same type in the above expressions. You should read the FAQ, as any good usenet netizen does before posting to a group. -- Joe Maun Montreal, QC Canada
|
Fri, 28 Nov 2003 12:29:31 GMT |
|
|
|