Re: De-referencing pointer to function-pointer

From: Edd (eddNOSPAMHERE_at_nunswithguns.net)
Date: 05/12/04


Date: Wed, 12 May 2004 16:48:53 +0100

Jack Klein wrote:

[ 8< - - - snip ]

Sorry to bother you again!...

> I have copied this from your original post:
>
>> /* Get the address of the kth element */
>> void *GetElement(ARRAY *a, unsigned k){
>> return (char *)(a->base) + (k * a->elsz);
>> }
>
> The first thing I would do is change the return type to "const void
> *", but that's not mandatory.

By a similar token, I guess I should have "const ARRAY *a" as the first
function argument, too (and similar things apply to some of the pointers
passed to my other functions).

> To retrieve a function pointer from your array, you can get rid of all
> that almost indecipherable casting by doing this:
>
> void *vp;
> vp = GetElement(&funct, 2);
> memcpy(&f, vp, sizeof f);
>
> The latter two lines can be combined, with rather less readability, to
> eliminate the need for the pointer to void:
>
> memcpy(&f, GetElement(&func, 2), sizeof f);

I just tried what you suggested, but got a number of compilation errors of
this kind:

amos $ gcc -Wall -ansi -pedantic ptrfunc.c -o ptrfunc -lm
ptrfunc.c: In function `main':
ptrfunc.c:48: warning: ANSI forbids passing arg 2 of `AddElement' between
function pointer and `void *'
[ 8< - - - remaining output snipped ]

A wise man once said:
"No, no, no, no. There is no correspondence between pointers to object
types and pointers to functions in C. Even attempting to convert between a
function pointer and a pointer to void, in either direction, is completely
undefined."

For completeness, here's the latest main() function:

int main(void){
        double (*f)(double);
        ARRAY funcs;
        InitArray(&funcs, sizeof(f));

        /* Add some functions to the funcs ARRAY */
        AddElement(&funcs, sin);
        AddElement(&funcs, tan);
        AddElement(&funcs, exp);
        AddElement(&funcs, log);

        /* Get the ARRAY element at index 2 */
        memcpy(&f, GetElement(&funcs, 2), sizeof(f));

        /* This should now display "f(1.0) = 2.718..."? */
        printf("f(%lf) = %lf\n", 1.0, f(1.0));

        return 0;
}

Is there any way to fix this? I assume that this means I can't use the same
function (AddElement) to add both primitive data and function pointers to an
ARRAY?

Also, I'm still a little confused about what (e.g.) this does:
memmove(target, sin, a->elsz);
which is effectively done in the call to AddElement(&funcs, sin).
Is it copying the first sizeof(f) bytes of the compiled code for the sin
function into the array block, or is it copying the address of sin (whatever
that means)? Should I not be doing AddElement(&funcs, &sin), anyway? As I
mentioned before, my knowledge of functions pointers in this respect is a
bit lacking! Any clarification would be greatly appreciated!

Thanks,
Edd



Relevant Pages

  • Re: sizeof(ptr) = ?
    ... A void * has the same representation as a char *. ... Char pointers which require additional data ... iff the default offset is 0. ...
    (comp.lang.c)
  • Re: Malloc code
    ... int xxx; ... As for not using the void pointer, I will have to do some further testing ... I just needed some insight on passing arrays of pointers. ... struct MCB *r1; ...
    (microsoft.public.vc.language)
  • Re: polymorphic design approach
    ... > polymorphism. ... * 'Device' pointers are stored so as to allow polymorphic ... virtual void handleMessage ...
    (alt.comp.lang.learn.c-cpp)
  • Re: Realloc and pointer arithmetics
    ... through an AVL tree that managed void* data. ... the C standard does not. ... My frist thought was actually to store into the tree pointers to array ...
    (comp.lang.c)
  • Re: On the creation of an API for containers in C
    ... pointers, and these dynamic vectors. ... where 'dyt' was basically a wrapper for an anonymous void pointer. ... cost of this approach), although, if one makes use of the dynamic-type ... typed void pointers' and 'tagged references' (where the value is essentially ...
    (comp.lang.c)