Dereferencing f-pointers, arrays of f-pointers, pointers to f-pointers 
Author Message
 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  
 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  
 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  
 
 [ 3 post ] 

 Relevant Pages 

1. Pointer of Pointers was Pointer of arrays...

2. Pointers: return of pointer to array of pointers to main

3. dereferencing pointer to a structure containing a pointer to int

4. Array of pointers, pointer to array...

5. array pointer/pointer array

6. arrays pointers array of pointers

7. memory leak: pointer->pointer->pointer->struct

8. memory block containing pointers, aka pointer to pointer i believe

9. pointers pointers pointers!!!

10. memory Leak: pointer->pointer->pointer->struct

11. Pointer Functions and Pointers to Pointer Functions

12. Pointer to Pointer to Pointer....

 

 
Powered by phpBB® Forum Software