Pointer to functions

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

    Pointer to functions

    I know that a variable (void *) is guaranteed to be able to store any
    pointer and to allow conversion back to the original pointer.

    I think, then, that I can store a pointer to a function in a (void *)
    variable and then convert it back to the original type and use it as a
    funtion.

    The question is: am I correct or there might be situations where this
    could fail?

    To clarify, here is an example of what I'm trying to do:

    /* Prototypes of functions that are defined somewhere */
    int f1(int x);
    void f2(int a, int b);

    /* Variables of type "pointers to functions" */
    int (*fa)(int);
    void (*fb)(int, int);

    /* An array of generic pointers */
    void *fun_vec[2];

    ..... /* later in the code ... */
    fun_vec[0] = f1; /* store pointers to f1 and f1 */
    fun_vec[1] = f2; /* into void * */

    ..... /* even later ... */
    fa = fun_vec[0]; /* get them back as pointers */
    fb = fun_vec[1]; /* to functions */

    fb(2,fa(3)); /* use the functions */

    ....



  • Jens Thoms Toerring

    #2
    Re: Pointer to functions

    Remo D. <rdwrote:
    I know that a variable (void *) is guaranteed to be able to store any
    pointer and to allow conversion back to the original pointer.
    I think, then, that I can store a pointer to a function in a (void *)
    variable and then convert it back to the original type and use it as a
    funtion.
    The question is: am I correct or there might be situations where this
    could fail?
    Unfortunately, function pointers aren't covered by the C standard
    as being convertible to a void pointer and back. There seem to be
    some architectures where this leads to problems. On the other hand
    in many cases you probably will be able to do so (e.g. on POSIX
    compliant systems this has to work or e.g. the dlopen() couldn't
    be used).
    To clarify, here is an example of what I'm trying to do:
    /* Prototypes of functions that are defined somewhere */
    int f1(int x);
    void f2(int a, int b);
    /* Variables of type "pointers to functions" */
    int (*fa)(int);
    void (*fb)(int, int);
    /* An array of generic pointers */
    void *fun_vec[2];
    .... /* later in the code ... */
    fun_vec[0] = f1; /* store pointers to f1 and f1 */
    fun_vec[1] = f2; /* into void * */
    .... /* even later ... */
    fa = fun_vec[0]; /* get them back as pointers */
    fb = fun_vec[1]; /* to functions */
    fb(2,fa(3)); /* use the functions */
    With most systems you should be fine doing it that way. Note that
    you also can write the last e.g. as

    fun_vec[ 1 ]( 2, fun_vec[ 0 ]( 3 ) );

    Regards, Jens
    --
    \ Jens Thoms Toerring ___ jt@toerring.de
    \______________ ____________ http://toerring.de

    Comment

    • Remo D.

      #3
      Re: Pointer to functions

      Jens Thoms Toerring ha scritto:
      >
      Unfortunately, function pointers aren't covered by the C standard
      as being convertible to a void pointer and back. There seem to be
      some architectures where this leads to problems. On the other hand
      in many cases you probably will be able to do so (e.g. on POSIX
      compliant systems this has to work or e.g. the dlopen() couldn't
      be used).
      >
      Thanks Jens! I found a draft of the C standard (N869) on the internet
      and, as you said, there's no mention of pointers to functions being
      convertible to void *.

      However, in section 6.3.2.3 paragraph 8 they say:
      >A pointer to a function of one type may be converted to
      >a pointer to a function of another type and back again;
      >the result shall compare equal to the original pointer.
      >If a converted pointer is used to call a function whose
      >type is not compatible with the pointed-to type, the
      >behavior is undefined.
      So, if I would declare an array of function pointers, should it be safer?

      /* array of 2 pointers to function returning int */
      int (*fun_vec[2])();

      Once I convert them to the appropriate function type, it should work (if
      I read the standard correctly).

      As you rightly pointed out it should also work as long as I use them
      correctly (I would expect compiler warnings, though).

      R:D

      Comment

      • vippstar@gmail.com

        #4
        Re: Pointer to functions

        On Jun 19, 5:40 pm, "Remo D." <rdwrote:
        I know that a variable (void *) is guaranteed to be able to store any
        pointer and to allow conversion back to the original pointer.
        It's a common extension to do so, (see Annex G ISO 9899:1999) but
        conforming programs should not rely on that.
        I think, then, that I can store a pointer to a function in a (void *)
        variable and then convert it back to the original type and use it as a
        funtion.
        Not allowed by ISO C.
        You are, however, allowed to convert any function pointer to any other
        function pointer and back, and get the same result.
        The question is: am I correct or there might be situations where this
        could fail?
        Yes, for example if a function pointer is not really a pointer, or
        cannot be represented by void *, etc.
        To clarify, here is an example of what I'm trying to do:
        >
        /* Prototypes of functions that are defined somewhere */
        int f1(int x);
        void f2(int a, int b);
        >
        /* Variables of type "pointers to functions" */
        int (*fa)(int);
        void (*fb)(int, int);
        >
        /* An array of generic pointers */
        void *fun_vec[2];
        >
        .... /* later in the code ... */
        fun_vec[0] = f1; /* store pointers to f1 and f1 */
        fun_vec[1] = f2; /* into void * */
        >
        .... /* even later ... */
        fa = fun_vec[0]; /* get them back as pointers */
        fb = fun_vec[1]; /* to functions */
        >
        fb(2,fa(3)); /* use the functions */
        Here's the fix:

        int f1(int);
        void f2(int, int);

        int (*fa)(int);
        void (*fb)(int, int);

        fa = f1;
        fb = f2;

        /* the type of function pointer really doesn't matter, I use void (*)
        () */
        void (*fun_vec[])() = { fa, fb }; /* I think a cast is not needed, but
        I'm not sure, anyone can help? */

        /* ... later ... */

        fa = fun_vec[0];
        fb = fun_vec[1];

        Comment

        • vippstar@gmail.com

          #5
          Re: Pointer to functions

          On Jun 19, 6:57 pm, vipps...@gmail. com wrote:
          On Jun 19, 5:40 pm, "Remo D." <rdwrote:I know that a variable (void *) is guaranteed to be able to store any
          pointer and to allow conversion back to the original pointer.
          >
          It's a common extension to do so, (see Annex G ISO 9899:1999) but
          Correction: Annex J, J.5

          Comment

          • Jens Thoms Toerring

            #6
            Re: Pointer to functions

            Remo D. <rdwrote:
            Jens Thoms Toerring ha scritto:

            Unfortunately, function pointers aren't covered by the C standard
            as being convertible to a void pointer and back. There seem to be
            some architectures where this leads to problems. On the other hand
            in many cases you probably will be able to do so (e.g. on POSIX
            compliant systems this has to work or e.g. the dlopen() couldn't
            be used).
            Thanks Jens! I found a draft of the C standard (N869) on the internet
            and, as you said, there's no mention of pointers to functions being
            convertible to void *.
            However, in section 6.3.2.3 paragraph 8 they say:
            >A pointer to a function of one type may be converted to
            >a pointer to a function of another type and back again;
            >the result shall compare equal to the original pointer.
            >If a converted pointer is used to call a function whose
            >type is not compatible with the pointed-to type, the
            >behavior is undefined.
            So, if I would declare an array of function pointers, should it be safer?
            /* array of 2 pointers to function returning int */
            int (*fun_vec[2])();
            Once I convert them to the appropriate function type, it should work (if
            I read the standard correctly).
            Yes, that's also how I would understand it.

            So

            fun_vec[ 1 ]( 2, fun_vec[ 0 ]( 3 ) );

            would be problematic, to say the least (and what I wrote in my last
            post was wrong since there they where void pointers...), while

            fa = fun_vec[0]; /* get them back as pointers */
            fb = fun_vec[1]; /* to functions */

            fb(2,fa(3)); /* use the functions */

            is ok.
            As you rightly pointed out it should also work as long as I use them
            correctly (I would expect compiler warnings, though).
            You can always cast them to the correct type to make the compiler
            happy. Using your example:

            fun_vec[0] = f1;
            fun_vec[1] = (int (*)()) f2;

            fa = fun_vec[0];
            fb = (void (*)()) fun_vec[1];

            or even

            fa = (int (*)(int)) fun_vec[0];
            fb = (void (*)(int, int)) fun_vec[1];

            Regards, Jens
            --
            \ Jens Thoms Toerring ___ jt@toerring.de
            \______________ ____________ http://toerring.de

            Comment

            • Remo D.

              #7
              Re: Pointer to functions

              vippstar@gmail. com ha scritto:
              >I think, then, that I can store a pointer to a function in a (void *)
              >variable and then convert it back to the original type and use it as a
              >funtion.
              Not allowed by ISO C.
              You are, however, allowed to convert any function pointer to any other
              function pointer and back, and get the same result.
              [...]
              Here's the fix:
              [...]
              void (*fun_vec[])() = { fa, fb }; /* I think a cast is not needed, but
              Thanks vippstar. I'll use an array of function pointers.

              Remo

              Comment

              • Remo D.

                #8
                Re: Pointer to functions

                Jens Thoms Toerring ha scritto:
                Remo D. <rdwrote:
                >As you rightly pointed out it should also work as long as I use them
                >correctly (I would expect compiler warnings, though).
                >
                You can always cast them to the correct type to make the compiler
                happy. Using your example:
                >
                fun_vec[0] = f1;
                fun_vec[1] = (int (*)()) f2;
                >
                fa = fun_vec[0];
                fb = (void (*)()) fun_vec[1];
                >
                or even
                >
                fa = (int (*)(int)) fun_vec[0];
                fb = (void (*)(int, int)) fun_vec[1];
                Thanks for the advice, Jens.

                I'll use an array of pointer to functions and will cast appropriately
                when assigning back to variable.

                Very useful discussion! (at least for me :) )

                RD

                Comment

                • Stephen Sprunk

                  #9
                  Re: Pointer to functions

                  Remo D. wrote:
                  I know that a variable (void *) is guaranteed to be able to store any
                  pointer and to allow conversion back to the original pointer.
                  A pointer-to-void is only guaranteed to be able to hold any
                  pointer-to-object. It is not guaranteed to be able to hold any
                  pointer-to-function.

                  However, it is guaranteed that you can convert a pointer-to-function to
                  a different type of pointer-to-function and back. This seems to be good
                  enough for what you want.
                  I think, then, that I can store a pointer to a function in a (void *)
                  variable and then convert it back to the original type and use it as a
                  funtion.
                  >
                  The question is: am I correct or there might be situations where this
                  could fail?
                  It is allowed to fail, though I'm not sure there are any real-world
                  systems where it will. Still, one should avoid code that isn't
                  guaranteed to work when there's a reasonably clear alternative that is.

                  S

                  Comment

                  • Eric Sosman

                    #10
                    Re: Pointer to functions

                    Stephen Sprunk wrote:
                    >
                    [Is void* <=funcptr conversion allowed?]
                    It is allowed to fail, though I'm not sure there are any real-world
                    systems where it will. [...]
                    I believe it produces a run-time error on IBM AS/400
                    (aka iSeries). Can anyone refute or confirm?

                    --
                    Eric.Sosman@sun .com

                    Comment

                    • Chris Torek

                      #11
                      Re: Pointer to functions

                      In article <q2y6k.6918$89. 2994@nlpi069.nb dc.sbc.com>
                      Stephen Sprunk <stephen@sprunk .orgwrote:
                      >[Using "void *" to hold function pointers] is allowed to fail,
                      >though I'm not sure there are any real-world systems where it will.
                      There are at least two: old DOS-based PCs (when using some of the
                      "memory models", in this case, when using 16-bit data, 32-bit-code
                      models); and IBM AS/400 machines.
                      >Still, one should avoid code that isn't guaranteed to work when
                      >there's a reasonably clear alternative that is.
                      Indeed. The methods described elsethread are probably *clearer*
                      than the version with plain "void *", at least once one gets past
                      the tricky concept of "array of pointer to function". (That is,
                      both methods are equally obscure if one does not understand the
                      concept in the first place, and "array of pointer to function"
                      has bizarre-looking syntax in C. These combine to make a fairly
                      large "mental digestion" step. Typedef aliases can help though.)
                      --
                      In-Real-Life: Chris Torek, Wind River Systems
                      Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
                      email: gmail (figure it out) http://web.torek.net/torek/index.html

                      Comment

                      • Richard Bos

                        #12
                        Re: Pointer to functions

                        "Remo D." <rdwrote:
                        Jens Thoms Toerring ha scritto:

                        Unfortunately, function pointers aren't covered by the C standard
                        as being convertible to a void pointer and back. There seem to be
                        some architectures where this leads to problems. On the other hand
                        in many cases you probably will be able to do so (e.g. on POSIX
                        compliant systems this has to work or e.g. the dlopen() couldn't
                        be used).
                        >
                        Thanks Jens! I found a draft of the C standard (N869) on the internet
                        and,
                        That is _very_ old. Search for n1256.pdf: it has the complete C99
                        Standard, plus TC 1 and 2, plus the last draft of TC 3.
                        as you said, there's no mention of pointers to functions being
                        convertible to void *.
                        >
                        However, in section 6.3.2.3 paragraph 8 they say:
                        >
                        >A pointer to a function of one type may be converted to
                        >a pointer to a function of another type and back again;
                        >the result shall compare equal to the original pointer.
                        So, if I would declare an array of function pointers, should it be safer?
                        >
                        /* array of 2 pointers to function returning int */
                        int (*fun_vec[2])();
                        >
                        Once I convert them to the appropriate function type, it should work (if
                        I read the standard correctly).
                        Yes. See also the FAQ: <http://c-faq.com/ptrs/generic.html>.

                        Richard

                        Comment

                        • CBFalconer

                          #13
                          Re: Pointer to functions

                          Richard Bos wrote:
                          "Remo D." <rdwrote:
                          >Jens Thoms Toerring ha scritto:
                          >>
                          >>Unfortunately , function pointers aren't covered by the C standard
                          >>as being convertible to a void pointer and back. There seem to be
                          >>some architectures where this leads to problems. On the other hand
                          >>in many cases you probably will be able to do so (e.g. on POSIX
                          >>compliant systems this has to work or e.g. the dlopen() couldn't
                          >>be used).
                          >>
                          >Thanks Jens! I found a draft of the C standard (N869) on the internet
                          >
                          That is _very_ old. Search for n1256.pdf: it has the complete C99
                          Standard, plus TC 1 and 2, plus the last draft of TC 3.
                          However it has minimal differences from the actual standard. If
                          you want an edited text copy, quite suitable for quoting in
                          newsgroups, and easily searched with text processing software, see:

                          <http://cbfalconer.home .att.net/download/n869_txt.bz2>

                          for a bzip2 compressed text version. There are no decent text
                          versions for anything later than N869.

                          --
                          [mail]: Chuck F (cbfalconer at maineline dot net)
                          [page]: <http://cbfalconer.home .att.net>
                          Try the download section.


                          ** Posted from http://www.teranews.com **

                          Comment

                          • Remo D.

                            #14
                            Re: Pointer to functions

                            CBFalconer ha scritto:
                            Richard Bos wrote:
                            >"Remo D." <rdwrote:
                            >>I found a draft of the C standard (N869) on the internet
                            >That is _very_ old. Search for n1256.pdf: it has the complete C99
                            >
                            However it has minimal differences from the actual standard. If
                            you want an edited text copy, quite suitable for quoting in
                            newsgroups, and easily searched with text processing software, see:
                            >
                            <http://cbfalconer.home .att.net/download/n869_txt.bz2>
                            Thanks for pointing me in the right direction. I've saved both the
                            n1256.pdf and the n869.txt. They'll make my life easier.

                            And shame on me for not having gone trhough the FAQ before posting!

                            R.D

                            Comment

                            • Richard

                              #15
                              Re: Pointer to functions

                              "Remo D." <rdwrites:
                              CBFalconer ha scritto:
                              >Richard Bos wrote:
                              >>"Remo D." <rdwrote:
                              >>>I found a draft of the C standard (N869) on the internet
                              >>That is _very_ old. Search for n1256.pdf: it has the complete C99
                              >>
                              >However it has minimal differences from the actual standard. If
                              >you want an edited text copy, quite suitable for quoting in
                              >newsgroups, and easily searched with text processing software, see:
                              >>
                              > <http://cbfalconer.home .att.net/download/n869_txt.bz2>
                              >
                              Thanks for pointing me in the right direction. I've saved both the
                              n1256.pdf and the n869.txt. They'll make my life easier.
                              >
                              And shame on me for not having gone trhough the FAQ before posting!
                              >
                              R.D
                              Please note that Falconer's copy is out of date and he is constantly
                              reminded of that but refuses to stop pimping it out. He seems unaware
                              that you can search and copy from a pdf too. One can only guess at his
                              motives.


                              Comment

                              Working...