De-referencing pointer to function-pointer

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Edd

    #1

    De-referencing pointer to function-pointer

    Hello all,

    I've made a data structure and an associated set of functions to enable me
    to store a dynamically-sized array of elements of whatever data type I like.
    Well that's the idea anyway...
    My implementation seems to work great for primitive types, structures and
    unions, but I can't quite get an array of function-pointers working
    properly. Here's a very reduced version of my code with error checks removed
    for the sake of brevity.

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <math.h>

    #define ALLOC_FACTOR 10

    /* Dynamically-allocated array structure */
    typedef struct TYPE_ARRAY {
    void *base;
    size_t elsz;
    unsigned block, len;
    }
    ARRAY;

    /* Initialise an array to an 'empty' state */
    int InitArray(ARRAY *a, size_t elsz){
    a->base = NULL;
    a->elsz = elsz;
    a->block = a->len = 0;
    return 0;
    }

    /* Add an element to an array */
    int AddElement(ARRA Y *a, void *el){
    /* Allocate some space if necessary */
    if(a->block == a->len){
    a->base = realloc(a->base, a->elsz*(a->block + ALLOC_FACTOR));
    a->block += ALLOC_FACTOR;
    }
    /* Copy a new element on to the end of the array */
    memmove((char *)(a->base) + (a->elsz*a->len++), el, a->elsz);
    return 0;
    }

    /* Get the address of the kth element */
    void *GetElement(ARR AY *a, unsigned k){
    return (char *)(a->base) + (k * a->elsz);
    }


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

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

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

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

    return 0;
    }


    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.
    Here's an alternative main() function which makes a dynamic array of doubles
    instead of function pointers. This one seems to work fine:

    int main(void){
    double src[4] = {0.0, 1.0, 3.14, 2.718};
    ARRAY dbls;
    InitArray(&dbls , sizeof(double)) ;
    double d;

    /* Add some doubles to the dbls ARRAY */
    AddElement(&dbl s, src);
    AddElement(&dbl s, src+1);
    AddElement(&dbl s, src+2);
    AddElement(&dbl s, src+3);

    /* Get the ARRAY element at index 2 */
    d = *(double *)GetElement(&d bls, 2);

    /* This should now display "d = 3.14" */
    printf("d = %lf\n", d);

    return 0;
    }


    Can anyone point me in the right direction?
    Thanks in advance,

    Edd

  • Jack Klein

    #2
    Re: De-referencing pointer to function-pointer

    On Tue, 11 May 2004 03:47:55 +0100, "Edd"
    <eddNOSPAMHERE@ nunswithguns.ne t> wrote in comp.lang.c:
    [color=blue]
    > Hello all,
    >
    > I've made a data structure and an associated set of functions to enable me
    > to store a dynamically-sized array of elements of whatever data type I like.
    > Well that's the idea anyway...
    > My implementation seems to work great for primitive types, structures and
    > unions, but I can't quite get an array of function-pointers working
    > properly. Here's a very reduced version of my code with error checks removed
    > for the sake of brevity.
    >
    > #include <stdio.h>
    > #include <stdlib.h>
    > #include <string.h>
    > #include <math.h>
    >
    > #define ALLOC_FACTOR 10
    >
    > /* Dynamically-allocated array structure */
    > typedef struct TYPE_ARRAY {
    > void *base;
    > size_t elsz;
    > unsigned block, len;
    > }
    > ARRAY;
    >
    > /* Initialise an array to an 'empty' state */
    > int InitArray(ARRAY *a, size_t elsz){
    > a->base = NULL;
    > a->elsz = elsz;
    > a->block = a->len = 0;
    > return 0;
    > }
    >
    > /* Add an element to an array */
    > int AddElement(ARRA Y *a, void *el){
    > /* Allocate some space if necessary */
    > if(a->block == a->len){
    > a->base = realloc(a->base, a->elsz*(a->block + ALLOC_FACTOR));
    > a->block += ALLOC_FACTOR;
    > }
    > /* Copy a new element on to the end of the array */
    > memmove((char *)(a->base) + (a->elsz*a->len++), el, a->elsz);
    > return 0;
    > }
    >
    > /* Get the address of the kth element */
    > void *GetElement(ARR AY *a, unsigned k){
    > return (char *)(a->base) + (k * a->elsz);
    > }
    >
    >
    > int main(void){
    > double (*f)(double);
    > ARRAY funcs;
    > InitArray(&func s, sizeof(sin));[/color]

    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]
    [color=blue]
    > 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.[/color]

    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_na me) 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.

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
    comp.lang.c++ http://www.parashift.com/c++-faq-lite/
    alt.comp.lang.l earn.c-c++

    Comment

    • Sameer

      #3
      Re: De-referencing pointer to function-pointer

      AddElement(&fun cs, &sin) is copying the first sizeof(double
      (*)(double)) bytes of instruction code of sin function, and not its
      address.

      Use,

      double (*fptrs[]) (double) = {sin, tan, exp, log};

      AddElement(&fun cs, fptrs);
      AddElement(&fun cs, fptrs + 1);
      AddElement(&fun cs, fptrs + 2);
      AddElement(&fun cs, fptrs + 3);

      HTH.

      -Sameer

      Comment

      • Edd

        #4
        Re: De-referencing pointer to function-pointer

        Jack Klein wrote:[color=blue]
        > On Tue, 11 May 2004 03:47:55 +0100, "Edd"
        > <eddNOSPAMHERE@ nunswithguns.ne t> wrote in comp.lang.c:[/color]

        [ 8< - - - snip ]
        [color=blue][color=green]
        >> int main(void){
        >> double (*f)(double);
        >> ARRAY funcs;
        >> InitArray(&func s, sizeof(sin));[/color]
        >
        > 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][/color]

        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?

        [color=blue][color=green]
        >> 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.[/color]
        >
        > 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_na me) 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.[/color]

        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(&func s, sizeof(void*));

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

        /* Get the ARRAY element at index 2 */
        f = (double (*)(double))*(v oid**)GetElemen t(&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

        Comment

        • Jack Klein

          #5
          Re: De-referencing pointer to function-pointer

          On Tue, 11 May 2004 13:54:48 +0100, "Edd"
          <eddNOSPAMHERE@ nunswithguns.ne t> wrote in comp.lang.c:
          [color=blue]
          > Jack Klein wrote:[color=green]
          > > On Tue, 11 May 2004 03:47:55 +0100, "Edd"
          > > <eddNOSPAMHERE@ nunswithguns.ne t> wrote in comp.lang.c:[/color]
          >
          > [ 8< - - - snip ]
          >[color=green][color=darkred]
          > >> int main(void){
          > >> double (*f)(double);
          > >> ARRAY funcs;
          > >> InitArray(&func s, sizeof(sin));[/color]
          > >
          > > 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][/color]
          >
          > 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?[/color]

          Not just should, but it required to. When a source program violates
          syntax or a constraint, the C standard requires the compiler to issue
          a diagnostic, although it does not specify the format of the
          diagnostic.

          I haven't used GCC ports much, nor recently, but I think you might
          need to add -pedantic.
          [color=blue][color=green][color=darkred]
          > >> 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.[/color]
          > >
          > > 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_na me) 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.[/color]
          >
          > 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(&func s, sizeof(void*));[/color]

          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.

          Fortunately, you don't need to. You already have a perfect operand
          here, just replace the line above with:

          InitArray(&func s, sizeof f);

          f is already a pointer to function, not the name of a function, so
          applying sizeof to it is just fine and dandy. Also, since f is an
          object and not a type, the parentheses are not necessary, but harmless
          if you prefer them.
          [color=blue]
          > /* Add some functions to the funcs ARRAY */
          > vptr = sin;
          > AddElement(&fun cs, &vptr);
          > vptr = tan;
          > AddElement(&fun cs, &vptr);
          > vptr = exp;
          > AddElement(&fun cs, &vptr);
          > vptr = log;
          > AddElement(&fun cs, &vptr);[/color]

          Leave out vptr completely, just omit if from your program. Now that
          you have uses sizeof f to initialize your structure, you can just do:

          AddElement(&fun cs, sin);
          AddElement(&fun cs, tan);

          ....and so on.

          No problem with using the name of a function without () as an argument
          passed to another function. Unlike with the sizeof operator, this is
          well defined and automatically converts the name of the function to a
          pointer to the function.
          [color=blue]
          > /* Get the ARRAY element at index 2 */
          > f = (double (*)(double))*(v oid**)GetElemen t(&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[/color]

          I have copied this from your original post:
          [color=blue]
          > /* Get the address of the kth element */
          > void *GetElement(ARR AY *a, unsigned k){
          > return (char *)(a->base) + (k * a->elsz);
          > }[/color]

          The first thing I would do is change the return type to "const void
          *", but that's not mandatory.

          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(&fun ct, 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(&fun c, 2), sizeof f);

          All the nasty casts are gone!

          --
          Jack Klein
          Home: http://JK-Technology.Com
          FAQs for
          comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
          comp.lang.c++ http://www.parashift.com/c++-faq-lite/
          alt.comp.lang.l earn.c-c++

          Comment

          • Edd

            #6
            Re: De-referencing pointer to function-pointer

            Jack Klein wrote:

            [ 8< - - - snip ]
            [color=blue]
            > 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.[/color]

            Apologies for that. I keep meaning to get a copy of the standard, but I'm a
            bit strapped for cash at the moment. I'll have one soonish though, with any
            luck. Should save on your mental anguish... :)
            [color=blue]
            > Fortunately, you don't need to. You already have a perfect operand
            > here, just replace the line above with:
            >
            > InitArray(&func s, sizeof f);
            >
            > f is already a pointer to function, not the name of a function, so
            > applying sizeof to it is just fine and dandy. Also, since f is an
            > object and not a type, the parentheses are not necessary, but harmless
            > if you prefer them.
            >[color=green]
            >> /* Add some functions to the funcs ARRAY */
            >> vptr = sin;
            >> AddElement(&fun cs, &vptr);
            >> vptr = tan;
            >> AddElement(&fun cs, &vptr);
            >> vptr = exp;
            >> AddElement(&fun cs, &vptr);
            >> vptr = log;
            >> AddElement(&fun cs, &vptr);[/color]
            >
            > Leave out vptr completely, just omit if from your program. Now that
            > you have uses sizeof f to initialize your structure, you can just do:
            >
            > AddElement(&fun cs, sin);
            > AddElement(&fun cs, tan);
            >
            > ...and so on.
            >
            > No problem with using the name of a function without () as an argument
            > passed to another function. Unlike with the sizeof operator, this is
            > well defined and automatically converts the name of the function to a
            > pointer to the function.[/color]

            [ 8< - - - snip ]
            [color=blue]
            > 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(&fun ct, 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(&fun c, 2), sizeof f);
            >
            > All the nasty casts are gone![/color]

            That's all splendid, Jack, thanks very much!

            Edd

            Comment

            • Ben Pfaff

              #7
              Re: De-referencing pointer to function-pointer

              Jack Klein <jackklein@spam cop.net> writes:
              [color=blue]
              > 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?[/color]

              He is the victim of an irritating GNU C extension. From the GNU
              C compiler manual:

              Arithmetic on `void'- and Function-Pointers
              =============== =============== =============

              In GNU C, addition and subtraction operations are supported
              on pointers to `void' and on pointers to functions. This is
              done by treating the size of a `void' or of a function as 1.

              --
              "I don't have C&V for that handy, but I've got Dan Pop."
              --E. Gibbons

              Comment

              • Edd

                #8
                Re: De-referencing pointer to function-pointer

                Jack Klein wrote:

                [ 8< - - - snip ]

                Sorry to bother you again!...
                [color=blue]
                > I have copied this from your original post:
                >[color=green]
                >> /* Get the address of the kth element */
                >> void *GetElement(ARR AY *a, unsigned k){
                >> return (char *)(a->base) + (k * a->elsz);
                >> }[/color]
                >
                > The first thing I would do is change the return type to "const void
                > *", but that's not mandatory.[/color]

                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).
                [color=blue]
                > 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(&fun ct, 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(&fun c, 2), sizeof f);[/color]

                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(&func s, sizeof(f));

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

                /* Get the ARRAY element at index 2 */
                memcpy(&f, GetElement(&fun cs, 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(&fun cs, 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(&fun cs, &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


                Comment

                • those who know me have no need of my name

                  #9
                  Re: De-referencing pointer to function-pointer

                  [slightly reordered]

                  in comp.lang.c i read:
                  [color=blue]
                  >ptrfunc.c: In function `main':
                  >ptrfunc.c:48 : warning: ANSI forbids passing arg 2 of `AddElement' between
                  >function pointer and `void *'[/color]
                  [color=blue]
                  >Is there any way to fix this?[/color]

                  not portably, as you can see from gcc's warning. it'll work with some
                  compilers, but it will fail elsewhere, and might fail even with a different
                  version of the same compiler or with just different options selected.
                  [color=blue]
                  >I assume that this means I can't use the same function (AddElement) to add
                  >both primitive data and function pointers to an ARRAY?[/color]

                  correct, you cannot do both in a portable / strictly conforming program.
                  [color=blue]
                  > /* Get the ARRAY element at index 2 */
                  > memcpy(&f, GetElement(&fun cs, 2), sizeof(f));[/color]

                  i have no idea why someone would bother with this bit of undefined behavior
                  instead of the much clearer but still undefined yet likely to have the same
                  result:

                  typedef double (*fptr)(double) ;
                  fptr f = (fptr)GetElemen t(&funcs, 2);
                  [color=blue]
                  >Should I not be doing AddElement(&fun cs, &sin), anyway?[/color]

                  a function's name without the () postfix operator yields a pointer to the
                  function, so there's no need to use the & prefix operator.
                  [color=blue]
                  >my knowledge of functions pointers in this respect is a
                  >bit lacking! Any clarification would be greatly appreciated![/color]

                  <http://www.function-pointer.org>

                  --
                  a signature

                  Comment

                  • Edd

                    #10
                    Re: De-referencing pointer to function-pointer

                    those who know me have no need of my name wrote:

                    [ 8< - - - snip ]
                    [color=blue][color=green]
                    >> I assume that this means I can't use the same function (AddElement)
                    >> to add both primitive data and function pointers to an ARRAY?[/color]
                    >
                    > correct, you cannot do both in a portable / strictly conforming
                    > program.
                    >[color=green]
                    >> /* Get the ARRAY element at index 2 */
                    >> memcpy(&f, GetElement(&fun cs, 2), sizeof(f));[/color][/color]

                    Ok, I might as well give up on this idea for now, or at least find a
                    longer-winded way to do things, tailored to functions.
                    [color=blue]
                    > i have no idea why someone would bother with this bit of undefined
                    > behavior instead of the much clearer but still undefined yet likely
                    > to have the same result:
                    >
                    > typedef double (*fptr)(double) ;
                    > fptr f = (fptr)GetElemen t(&funcs, 2);[/color]

                    Even if AddElement did exactly what it should do intuitively (which, as
                    we've discussed, is pretty much impossible to achieve in a portable way), it
                    would mean that this call to GetElement would return the /address/ of a
                    function-pointer and not a function-pointer 'disguised' as (void*). So
                    casting it to type fptr is no good. If anything, it would have to be casted
                    to a double (**)(double) and de-referenced.

                    It's all pointless anyway. Wreaks of un-definedness as you and Jack have
                    indicated, so I'll leave it alone!

                    [ 8< - - - snip ]
                    [color=blue]
                    > <http://www.function-pointer.org>[/color]

                    I'll have a look at that! Thanks for your help,

                    Edd

                    Comment

                    • Michael Wojcik

                      #11
                      Re: De-referencing pointer to function-pointer


                      In article <m1y8nwd4ms.gnu s@usa.net>, those who know me have no need of my name <not-a-real-address@usa.net > writes:[color=blue]
                      >
                      > a function's name without the () postfix operator yields a pointer to the
                      > function, so there's no need to use the & prefix operator.[/color]

                      Except when it's the operand of the & operator (so you don't get a
                      pointer to a pointer to function), or of the sizeof operator, which
                      is why

                      sizeof sin

                      is not simply equivalent to

                      sizeof &sin

                      or

                      sizeof(double (*)(double))

                      I notice n869 has a footnote (#47) specifically noting this sizeof
                      exception, but it doesn't say why. (Maybe the committee felt that
                      people would assume that "sizeof function" would give them the size
                      of the code generated for function, which they might then try to use
                      for some horrible and unportable purpose.) Must get a copy of the
                      Rationale one of these days...

                      --
                      Michael Wojcik michael.wojcik@ microfocus.com

                      HTML is as readable as C. You can take this either way. -- Charlie Gibbs

                      Comment

                      • Arthur J. O'Dwyer

                        #12
                        Re: De-referencing pointer to function-pointer


                        On Thu, 13 May 2004, Michael Wojcik wrote:[color=blue]
                        >
                        > those who know me have no need of my name writes:[color=green]
                        > >
                        > > a function's name without the () postfix operator yields a pointer to
                        > > the function, so there's no need to use the & prefix operator.[/color]
                        >
                        > Except when it's the operand of the & operator (so you don't get a
                        > pointer to a pointer to function), or of the sizeof operator, which
                        > is why
                        > sizeof sin
                        > is not simply equivalent to
                        > sizeof &sin[/color]
                        [color=blue]
                        > I notice n869 has a footnote (#47) specifically noting this sizeof
                        > exception, but it doesn't say why.[/color]

                        Symmetry and consistency between the handling of arrays and the
                        handling of functions. Both "decay" under the same circumstances.
                        Since 'sizeof array' gives the size of the *array*, not the size of
                        the decayed pointer, 'sizeof function' should not give the size of
                        the decayed pointer either. However, "the size of the function"
                        doesn't make any sense w.r.t. C's abstract semantics; thus, 'sizeof
                        function' is disallowed.
                        [color=blue]
                        > (Maybe the committee felt that
                        > people would assume that "sizeof function" would give them the size
                        > of the code generated for function, which they might then try to use
                        > for some horrible and unportable purpose.)[/color]

                        Letting the user get the "size of" a function is useless, since
                        you can't do arithmetic on function pointers, nor read or store
                        through them. So if the Standard were to allow this construct, its
                        semantics would basically be, "sizeof f, where f is a function,
                        shall return a number. There's nothing you can do with this number,
                        but it's supposed to be bigger for more complicated functions, in
                        general." That's silly.
                        Implementations are perfectly free to define 'sizeof f' themselves
                        to be whatever they want, AFAIK.

                        -Arthur

                        Comment

                        Working...