Re: De-referencing pointer to function-pointer

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


Date: Tue, 11 May 2004 13:54:48 +0100

Jack Klein wrote:
> On Tue, 11 May 2004 03:47:55 +0100, "Edd"
> <eddNOSPAMHERE@nunswithguns.net> wrote in comp.lang.c:

[ 8< - - - snip ]

>> int main(void){
>> double (*f)(double);
>> ARRAY funcs;
>> InitArray(&funcs, sizeof(sin));
>
> Either your compiler is broken or you are not invoking it as a C
> compiler and making use of some implementation-defined extension. It
> is a constraint violation to apply the sizeof operator to a function
> designator, and requires a diagnostic.
>
> The expression "sizeof(sin)" has literally no meaning in C. I have no
> idea what value your compiler generates when you apply sizeof to a
> function. Do you?
>
> [snip]

I see. Indeed I don't understand what my compiler generates under these
circumstances! However my compiler does not complain about this code in the
slightest, even when I turn on all warnings and support strict ANSI C. I'm
using MinGW under win2k with this command line:

gcc -Wall -ansi ptrtest.c -o ptrtest.exe

I just tried this on my University system with gcc on unix and I got errors.
Is this a problem with my home compiler, do you think -- should it warn me?

>> This program crashes when I run it. Am I doing something undefined
>> here? I can't see what's going wrong. I think it may be my
>> understanding of function-pointer syntax is a little lacking, but
>> what I've got still seems fine to me.
>
> Yes, you are doing something undefined here. Function and array names
> are not converted to pointers when used as operands of the sizeof
> operator.
>
> sizeof(array_name) yields the size, in bytes, of an array, not of a
> pointer to the element type of the array.
>
> sizeof(function_name) would request the compiler to yield the size, in
> bytes, of the function, not of a pointer to the function. But
> functions have no sizes accessible to a C program, and that use of
> sizeof is specifically illegal under the C standard.

I see. Thanks for the clarification.
This leads me on to the obvious follow-up question -- is there a way of
achieving the desired result? I can use the alternative method below (which
works correctly), but it's not quite as elegant as I would like:

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

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

    /* Get the ARRAY element at index 2 */
    f = (double (*)(double))*(void**)GetElement(&funcs, 2);

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

    return 0;
}

Thanks for you reply,
Edd