Do not cast pointers to functions to pointers to primitive types

Discussion in 'C Programming' started by ajaybgr, Sep 3, 2012.

  1. ajaybgr

    ajaybgr Guest

    Not sure if this is the right place or OT.
    One of the Parasoft coding guidelines (which I am using for current project) is
    "Do not cast pointers to functions to pointers to primitive types [CODSTA-09-3]"

    EXAMPLE(from parasoft document):
    void Foo(char *ptrC)
    {
    *ptrC = 0;
    return;
    }

    void f()
    {
    void *ptrV = 0;
    void (*funPtr) (char*) = 0;
    funPtr = &Foo;
    ptrV = (void*)funPtr; // Violation of the rule and raise error
    return;
    }

    I can see why it is a bad idea not to write code this way.
    But can any one explain where this kind of code is useful?
    (imo, to be a guideline it must have been used/misused a lot)
    Where casting a function pointer to primitive type makes sense?
    Sorry if this is too silly, my mind seems to have hit a wall today.

    Regards
    Ajay
    ajaybgr, Sep 3, 2012
    #1
    1. Advertising

  2. ajaybgr

    Ian Collins Guest

    On 09/ 3/12 08:50 PM, ajaybgr wrote:
    > Not sure if this is the right place or OT.
    > One of the Parasoft coding guidelines (which I am using for current project) is
    > "Do not cast pointers to functions to pointers to primitive types [CODSTA-09-3]"
    >
    > EXAMPLE(from parasoft document):
    > void Foo(char *ptrC)
    > {
    > *ptrC = 0;
    > return;
    > }
    >
    > void f()
    > {
    > void *ptrV = 0;
    > void (*funPtr) (char*) = 0;
    > funPtr =&Foo;
    > ptrV = (void*)funPtr; // Violation of the rule and raise error
    > return;
    > }
    >
    > I can see why it is a bad idea not to write code this way.
    > But can any one explain where this kind of code is useful?


    In a bad dream...

    > (imo, to be a guideline it must have been used/misused a lot)
    > Where casting a function pointer to primitive type makes sense?


    An awful lot of bad C code has been has been hacked together in the past
    30+ years!

    --
    Ian Collins
    Ian Collins, Sep 3, 2012
    #2
    1. Advertising

  3. On Sep 3, 9:50 am, ajaybgr <> wrote:

    > Not sure if this is the right place or OT.
    > One of the Parasoft coding guidelines (which I am using for current project) is
    > "Do not cast pointers to functions to pointers to primitive types [CODSTA-09-3]"
    >
    > EXAMPLE(from parasoft document):
    > void Foo(char *ptrC)
    > {
    >     *ptrC = 0;
    >     return;
    >
    > }
    >
    > void f()
    > {
    >     void *ptrV = 0;
    >     void (*funPtr) (char*) = 0;
    >     funPtr = &Foo;
    >     ptrV = (void*)funPtr; // Violation of the rule and raise error
    >     return;
    >
    > }
    >
    > I can see why it is a bad idea not to write code this way.
    > But can any one explain where this kind of code is useful?
    > (imo, to be a guideline it must have been used/misused a lot)
    > Where casting a function pointer to primitive type makes sense?
    > Sorry if this is too silly, my mind seems to have hit a wall today.


    it probably arises from the misconception that "void* is a pointer to
    anything" since on most architectures object pointers and functions
    pointers are "just addreses" you can get away with it a lot of the
    time. Yes it is a bad idea.
    Nick Keighley, Sep 3, 2012
    #3
  4. ajaybgr <> writes:

    > Not sure if this is the right place or OT. One of the Parasoft coding
    > guidelines (which I am using for current project) is "Do not cast
    > pointers to functions to pointers to primitive types [CODSTA-09-3]"
    >
    > EXAMPLE(from parasoft document):
    > void Foo(char *ptrC)
    > {
    > *ptrC = 0;
    > return;
    > }
    >
    > void f()
    > {
    > void *ptrV = 0;
    > void (*funPtr) (char*) = 0;
    > funPtr = &Foo;
    > ptrV = (void*)funPtr; // Violation of the rule and raise error
    > return;
    > }
    >
    > I can see why it is a bad idea not to write code this way.
    > But can any one explain where this kind of code is useful?
    > (imo, to be a guideline it must have been used/misused a lot)
    > Where casting a function pointer to primitive type makes sense?


    Like others, I can't really answer your question except to add that
    these sorts of conversion are undefined according to the definition of
    C. It's possible, then, that the rule is in your coding guidelines, not
    because it's so tempting, but simply because it's a no-so-well-known
    rule of the language.

    --
    Ben.
    Ben Bacarisse, Sep 3, 2012
    #4
  5. ajaybgr

    James Kuyper Guest

    On 09/03/2012 04:50 AM, ajaybgr wrote:
    > Not sure if this is the right place or OT.
    > One of the Parasoft coding guidelines (which I am using for current project) is
    > "Do not cast pointers to functions to pointers to primitive types [CODSTA-09-3]"
    >
    > EXAMPLE(from parasoft document):
    > void Foo(char *ptrC)
    > {
    > *ptrC = 0;
    > return;
    > }
    >
    > void f()
    > {
    > void *ptrV = 0;
    > void (*funPtr) (char*) = 0;
    > funPtr = &Foo;
    > ptrV = (void*)funPtr; // Violation of the rule and raise error
    > return;
    > }
    >
    > I can see why it is a bad idea not to write code this way.
    > But can any one explain where this kind of code is useful?
    > (imo, to be a guideline it must have been used/misused a lot)
    > Where casting a function pointer to primitive type makes sense?
    > Sorry if this is too silly, my mind seems to have hit a wall today.


    There are real platforms, in common use, where the behavior of such
    code, while not defined by the C standard, is defined by some other
    standard, and there's a fair amount of code written for those platforms
    which actually relies upon that assumption. This produces the
    unjustified but understandable belief that the technique will work
    everywhere.

    Example: the dlsym() function is specified by the X-open standard to
    take a void* argument which can be either a pointer to an object or a
    pointer to a function. The Rationale for that function notes;

    > ... the ISO C standard does not require that an object of type void * can hold a pointer to a function. Implementations supporting the XSI extension, however, do require that an object of type void * can hold a pointer to a function. The result of converting a pointer to a function into a pointer to another data type (except void *) is still undefined, however. Note that compilers conforming to the ISO C standard are required to generate a warning if a conversion from a void * pointer to a function pointer is attempted ...
    > Due to the problem noted here, a future version may either add a new function to return function pointers, or the current interface may be deprecated in favor of two new functions: one that returns data pointers and the other that returns function pointers.

    --
    James Kuyper
    James Kuyper, Sep 3, 2012
    #5
  6. James Kuyper <> writes:
    [...]
    > Example: the dlsym() function is specified by the X-open standard to
    > take a void* argument which can be either a pointer to an object or a
    > pointer to a function. The Rationale for that function notes;
    >

    [...]
    >> Note that compilers conforming to the ISO C standard are required to
    >> generate a warning if a conversion from a void * pointer to a
    >> function pointer is attempted.

    [...]

    I don't believe that's correct. The behavior of converting a void*
    pointer to a function pointer is not defined, but as far as I can tell
    it doesn't violate any constraint.

    A concrete example:

    int obj;
    void *vp = &obj;
    void (*fp)(void) = (void (*)(void))vp;

    The constraints on a cast operator are described in N1570 6.5.4.
    The cast in the above code doesn't violate any of them. (Perhaps
    there *should* be such a constraint.)

    Or am I missing something?

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Will write code for food.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Sep 3, 2012
    #6
  7. ajaybgr

    James Kuyper Guest

    On 09/03/2012 04:21 PM, Keith Thompson wrote:
    > James Kuyper <> writes:
    > [...]
    >> Example: the dlsym() function is specified by the X-open standard to
    >> take a void* argument which can be either a pointer to an object or a
    >> pointer to a function. The Rationale for that function notes;
    >>

    > [...]
    >>> Note that compilers conforming to the ISO C standard are required to
    >>> generate a warning if a conversion from a void * pointer to a
    >>> function pointer is attempted.

    > [...]
    >
    > I don't believe that's correct. The behavior of converting a void*
    > pointer to a function pointer is not defined, but as far as I can tell
    > it doesn't violate any constraint.
    >
    > A concrete example:
    >
    > int obj;
    > void *vp = &obj;
    > void (*fp)(void) = (void (*)(void))vp;
    >
    > The constraints on a cast operator are described in N1570 6.5.4.
    > The cast in the above code doesn't violate any of them. (Perhaps
    > there *should* be such a constraint.)
    >
    > Or am I missing something?


    It's possible that they're referring to implicit conversion, rather than
    one using a cast.
    --
    James Kuyper
    James Kuyper, Sep 3, 2012
    #7
  8. James Kuyper <> writes:
    > On 09/03/2012 04:21 PM, Keith Thompson wrote:
    >> James Kuyper <> writes:
    >> [...]
    >>> Example: the dlsym() function is specified by the X-open standard to
    >>> take a void* argument which can be either a pointer to an object or a
    >>> pointer to a function. The Rationale for that function notes;
    >>>

    >> [...]
    >>>> Note that compilers conforming to the ISO C standard are required to
    >>>> generate a warning if a conversion from a void * pointer to a
    >>>> function pointer is attempted.

    >> [...]
    >>
    >> I don't believe that's correct. The behavior of converting a void*
    >> pointer to a function pointer is not defined, but as far as I can tell
    >> it doesn't violate any constraint.

    [...]
    >
    > It's possible that they're referring to implicit conversion, rather than
    > one using a cast.


    It's possible, but if so they phrased it poorly.

    Note that gcc also appears to get this wrong (assuming my interpretation
    is correct). With "-std=c11 -pedantic", gcc 4.7 complains:

    warning: ISO C forbids conversion of object pointer to function pointer type [-pedantic]

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Will write code for food.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Sep 3, 2012
    #8
  9. ajaybgr

    Alan Curry Guest

    In article <>,
    Keith Thompson <> wrote:
    >James Kuyper <> writes:
    >> On 09/03/2012 04:21 PM, Keith Thompson wrote:
    >>> James Kuyper <> writes:
    >>> [...]
    >>>> Example: the dlsym() function is specified by the X-open standard to
    >>>> take a void* argument which can be either a pointer to an object or a
    >>>> pointer to a function. The Rationale for that function notes;
    >>>>
    >>> [...]
    >>>>> Note that compilers conforming to the ISO C standard are required to
    >>>>> generate a warning if a conversion from a void * pointer to a
    >>>>> function pointer is attempted.
    >>> [...]
    >>>
    >>> I don't believe that's correct. The behavior of converting a void*
    >>> pointer to a function pointer is not defined, but as far as I can tell
    >>> it doesn't violate any constraint.

    >[...]
    >>
    >> It's possible that they're referring to implicit conversion, rather than
    >> one using a cast.

    >
    >It's possible, but if so they phrased it poorly.


    Any idiot should be able to read that and know without being told that using
    a cast will get rid of the warning. Casts do that. It's obvious.

    --
    Alan Curry
    Alan Curry, Sep 3, 2012
    #9
  10. On 03/09/2012 22:21, Keith Thompson wrote:
    [..]
    > A concrete example:
    >
    > int obj;
    > void *vp = &obj;
    > void (*fp)(void) = (void (*)(void))vp;
    >
    > The constraints on a cast operator are described in N1570 6.5.4.
    > The cast in the above code doesn't violate any of them. (Perhaps
    > there*should* be such a constraint.)
    >
    > Or am I missing something?


    My understanding is that there is not such a constraint to allow
    such casts as a "common extension", N1570 J.5.7:

    A pointer to an object or to void may be cast to a pointer
    to a function, allowing data to be invoked as a function (6.5.4).

    A pointer to a function may be cast to a pointer to an object or to
    void, allowing a function to be inspected or modified (for example,
    by a debugger) (6.5.4).

    If that cast violated a constraint any implementation with such
    extension would be nonconforming. I only see a warning with gcc
    however when `-pedantic' is enabled.

    --
    Vincenzo Mercuri
    Vincenzo Mercuri, Sep 3, 2012
    #10
  11. (Alan Curry) writes:
    > In article <>,
    > Keith Thompson <> wrote:
    >>James Kuyper <> writes:
    >>> On 09/03/2012 04:21 PM, Keith Thompson wrote:
    >>>> James Kuyper <> writes:
    >>>> [...]
    >>>>> Example: the dlsym() function is specified by the X-open standard to
    >>>>> take a void* argument which can be either a pointer to an object or a
    >>>>> pointer to a function. The Rationale for that function notes;
    >>>>>
    >>>> [...]
    >>>>>> Note that compilers conforming to the ISO C standard are required to
    >>>>>> generate a warning if a conversion from a void * pointer to a
    >>>>>> function pointer is attempted.
    >>>> [...]
    >>>>
    >>>> I don't believe that's correct. The behavior of converting a void*
    >>>> pointer to a function pointer is not defined, but as far as I can tell
    >>>> it doesn't violate any constraint.

    >>[...]
    >>>
    >>> It's possible that they're referring to implicit conversion, rather than
    >>> one using a cast.

    >>
    >>It's possible, but if so they phrased it poorly.

    >
    > Any idiot should be able to read that and know without being told that using
    > a cast will get rid of the warning. Casts do that. It's obvious.


    Were you aware that we're talking about conversion from void* to
    a function pointer, a conversion whose behavior is not defined by
    the standard, whether it's done by a cast or not? This is quite
    distinct from other pointer-to-pointer conversions, which in most
    cases merely yield an implementation-defined result.

    I posted a code snippet upthread. Here's a small complete program:

    int main(void) {
    int obj;
    void *vp = &obj;
    void (*fp)(void) = (void (*)(void))vp; /* line 4 */
    return 0;
    }

    When I compile this with gcc 4.7, with "-pedantic" and any of
    "-std={c90,c99,c11}", I get the following warning:

    c.c:4:24: warning: ISO C forbids conversion of object pointer to function pointer type [-pedantic]

    I get the same warning with or without the (void (*)(void)) cast.
    (Without the cast, it's definitely a constraint violation.)

    You might want to reconsider your "Any idiot" statement.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Will write code for food.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Sep 4, 2012
    #11
  12. ajaybgr

    Kaz Kylheku Guest

    On 2012-09-03, ajaybgr <> wrote:
    > Not sure if this is the right place or OT.
    > One of the Parasoft coding guidelines (which I am using for current project) is
    > "Do not cast pointers to functions to pointers to primitive types [CODSTA-09-3]"


    [ snip ]

    > I can see why it is a bad idea not to write code this way.
    > But can any one explain where this kind of code is useful?


    Such code is found in the implementation of shared libraries.

    For instance, the dlsym function on POSIX returns void *,
    and this function is used whether you're looking up a function or some other
    kind of symbol.

    There is nothing wrong with doing this, except that it's not "maximally
    portable".

    For instance, here is one potential problem: what if function pointers are 48
    bits wide and object pointers 32 bits wide.

    If you're sure that portability isn't an issue, then it may be the best way to
    solve the kind of problem that it solves, because doing it portably (e.g. with
    unions to store two kinds of pointers in the same space) may add some clutter
    to the program.

    > (imo, to be a guideline it must have been used/misused a lot)
    > Where casting a function pointer to primitive type makes sense?


    Where you're going to cast it back to a function pointer type later.

    Say you have a linked list which stores "void *" items and you want to
    put function pointers in it.
    Kaz Kylheku, Sep 4, 2012
    #12
  13. Vincenzo Mercuri <> writes:
    > On 03/09/2012 22:21, Keith Thompson wrote:
    > [..]
    >> A concrete example:
    >>
    >> int obj;
    >> void *vp = &obj;
    >> void (*fp)(void) = (void (*)(void))vp;
    >>
    >> The constraints on a cast operator are described in N1570 6.5.4.
    >> The cast in the above code doesn't violate any of them. (Perhaps
    >> there*should* be such a constraint.)
    >>
    >> Or am I missing something?

    >
    > My understanding is that there is not such a constraint to allow
    > such casts as a "common extension", N1570 J.5.7:
    >
    > A pointer to an object or to void may be cast to a pointer
    > to a function, allowing data to be invoked as a function (6.5.4).
    >
    > A pointer to a function may be cast to a pointer to an object or to
    > void, allowing a function to be inspected or modified (for example,
    > by a debugger) (6.5.4).
    >
    > If that cast violated a constraint any implementation with such
    > extension would be nonconforming. I only see a warning with gcc
    > however when `-pedantic' is enabled.


    It's not necessary to omit a constraint to allow an extension like
    this. Many extensions give meaning to code that would otherwise
    violate a constraint or syntax rule. The compiler has to issue
    a diagnostic (which can be a non-fatal warning) if it's invoked
    in conforming mode; once it's issued the warning, it's free to do
    whatever the extension specifies. And/or the compiler can have a
    non-conforming mode that implements the extension without complaint.

    An example: gcc permits arithmetic on void* pointers as an extension.
    Any such arithmetic is a constraint violation.

    Looking through the list of common extensions in J.5, some of
    them can break strictly conforming programs, which violates 4p6.
    Predefined macro names not starting with an underscore are one
    example.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Will write code for food.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Sep 4, 2012
    #13
  14. ajaybgr

    Alan Curry Guest

    In article <>,
    Keith Thompson <> wrote:
    > (Alan Curry) writes:
    >>
    >> Any idiot should be able to read that and know without being told that using
    >> a cast will get rid of the warning. Casts do that. It's obvious.

    >

    [...]
    >
    >I posted a code snippet upthread. Here's a small complete program:
    >
    > int main(void) {
    > int obj;
    > void *vp = &obj;
    > void (*fp)(void) = (void (*)(void))vp; /* line 4 */
    > return 0;
    > }
    >
    >When I compile this with gcc 4.7, with "-pedantic" and any of
    >"-std={c90,c99,c11}", I get the following warning:
    >
    > c.c:4:24: warning: ISO C forbids conversion of object pointer to
    >function pointer type [-pedantic]
    >
    >I get the same warning with or without the (void (*)(void)) cast.
    >(Without the cast, it's definitely a constraint violation.)
    >
    >You might want to reconsider your "Any idiot" statement.


    I reassert "idiot" in the direction of gcc then. Casts should be silent.

    --
    Alan Curry
    Alan Curry, Sep 4, 2012
    #14
  15. (Alan Curry) writes:
    > In article <>,
    > Keith Thompson <> wrote:
    >> (Alan Curry) writes:
    >>>
    >>> Any idiot should be able to read that and know without being told that using
    >>> a cast will get rid of the warning. Casts do that. It's obvious.

    >>

    > [...]
    >>
    >>I posted a code snippet upthread. Here's a small complete program:
    >>
    >> int main(void) {
    >> int obj;
    >> void *vp = &obj;
    >> void (*fp)(void) = (void (*)(void))vp; /* line 4 */
    >> return 0;
    >> }
    >>
    >>When I compile this with gcc 4.7, with "-pedantic" and any of
    >>"-std={c90,c99,c11}", I get the following warning:
    >>
    >> c.c:4:24: warning: ISO C forbids conversion of object pointer to
    >>function pointer type [-pedantic]
    >>
    >>I get the same warning with or without the (void (*)(void)) cast.
    >>(Without the cast, it's definitely a constraint violation.)
    >>
    >>You might want to reconsider your "Any idiot" statement.

    >
    > I reassert "idiot" in the direction of gcc then. Casts should be silent.


    So you don't want to distinguish between casts whose behavior
    is well defined, those whose behavior is implementation-defined,
    and those whose behavior is completely undefined?

    I can understand that opinion, but it hardly seems reasonable to
    call those who disagrees with it idiots.

    Casts are commonly interpreted to mean "Shut up, compiler, I know
    what I'm doing"-- but the standard doesn't say or imply that.

    How do you feel about casts applied to struct types, which are a
    constraint violation?

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Will write code for food.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Sep 4, 2012
    #15
  16. ajaybgr

    Alan Curry Guest

    In article <>,
    Keith Thompson <> wrote:
    >
    >So you don't want to distinguish between casts whose behavior
    >is well defined, those whose behavior is implementation-defined,
    >and those whose behavior is completely undefined?
    >
    >I can understand that opinion, but it hardly seems reasonable to
    >call those who disagrees with it idiots.
    >
    >Casts are commonly interpreted to mean "Shut up, compiler, I know
    >what I'm doing"-- but the standard doesn't say or imply that.
    >
    >How do you feel about casts applied to struct types, which are a
    >constraint violation?


    Those are errors, not warnings. You can't cast away an error.

    Failure to distinguish errors and warnings is a problem that only The
    Standard has. In the real world everybody knows they're different.

    --
    Alan Curry
    Alan Curry, Sep 4, 2012
    #16
  17. ajaybgr

    James Kuyper Guest

    On 09/04/2012 04:27 PM, Alan Curry wrote:
    > In article <>,
    > Keith Thompson <> wrote:
    >>
    >> So you don't want to distinguish between casts whose behavior
    >> is well defined, those whose behavior is implementation-defined,
    >> and those whose behavior is completely undefined?
    >>
    >> I can understand that opinion, but it hardly seems reasonable to
    >> call those who disagrees with it idiots.
    >>
    >> Casts are commonly interpreted to mean "Shut up, compiler, I know
    >> what I'm doing"-- but the standard doesn't say or imply that.
    >>
    >> How do you feel about casts applied to struct types, which are a
    >> constraint violation?

    >
    > Those are errors, not warnings. You can't cast away an error.
    >
    > Failure to distinguish errors and warnings is a problem that only The
    > Standard has. In the real world everybody knows they're different.


    The standard cannot distinguish between error messages and warning
    messages, because whether or not something constitutes an error is
    highly dependent on factors outside the scope of the standard. The code
    in question has undefined behavior, the worst thing that the standard
    can say about any code construct. However, the X/Open standard does
    define the behavior (a fact which is outside the scope of the C
    standard). A programmer who decides to write code which relies upon that
    definition, believing that it will only ever need to be run on systems
    that conform to the X/Open standard (something else that is also outside
    the scope of the C standard) is NOT making an error (unless that belief
    is incorrect).

    The standard leaves the distinction between errors and warnings up to
    the implementations. Were you rewriting the C standard to remove that
    freedom, how would you make that distinction in such a way as to apply
    to cases like this? It seems to me that a mind-reading compiler with the
    capacity to make better judgements than the developer about the
    reasonability of such beliefs is needed, in order to make that distinction.
    James Kuyper, Sep 4, 2012
    #17
  18. On Tue, 4 Sep 2012 20:27:14 +0000 (UTC), (Alan
    Curry) wrote:

    >In article <>,
    >Keith Thompson <> wrote:
    >>
    >>So you don't want to distinguish between casts whose behavior
    >>is well defined, those whose behavior is implementation-defined,
    >>and those whose behavior is completely undefined?
    >>
    >>I can understand that opinion, but it hardly seems reasonable to
    >>call those who disagrees with it idiots.
    >>
    >>Casts are commonly interpreted to mean "Shut up, compiler, I know
    >>what I'm doing"-- but the standard doesn't say or imply that.
    >>
    >>How do you feel about casts applied to struct types, which are a
    >>constraint violation?

    >
    >Those are errors, not warnings. You can't cast away an error.


    Of course you can. Consider

    int * x = NULL;
    float *y = x;

    This is an error. Adding the appropriate cast to the last expression
    eliminates the error.
    >
    >Failure to distinguish errors and warnings is a problem that only The
    >Standard has. In the real world everybody knows they're different.


    Yes, but not everyone agrees on which side of the line a particular
    situation falls, or even if the situation always falls on the same
    side of the line.

    --
    Remove del for email
    Barry Schwarz, Sep 4, 2012
    #18
  19. ajaybgr

    Philip Lantz Guest

    Scott Fluhrer wrote:
    > Actually, if you are in such a circumstance (where you need to store a
    > function pointer, and some infrastructure only gives you a void * to store
    > it in), there is a totally portable way to handle it. Instead of attempting
    > to store the function pointer into the void * type, store a pointer to a
    > pointer to the function instead, For example:


    Your suggestion is workable, but your example doesn't work.

    > typedef void (*function)(int, double, char *);
    >
    > void my_function(int a, double b, char *c);
    > function *p_my_function = &my_function; /* p_my_function is a pointer to a
    > 'primitive type', specifically, a function pointer type */


    The above initialization is still attempting to store a pointer to a
    function in a pointer to a pointer to a function. You haven't defined an
    object for p_my_function to point to.

    > struct linked_list {
    > void *data;
    > }
    >
    > /* Functions which uses the linked_list type */
    > struct linked_list *p;
    > p->data = p_my_function; /* Completely portable, because we can assign a
    > data pointer to a void * type */
    >
    > ...
    >
    > function *func = p->data; /* Again, completely portable; the pointer func
    > is a data pointer */
    > (*func)( 7, 3.14159, "Hi ma!" );



    I think what you meant is:

    function p_my_function = &my_function;
    function *pp_my_function = &p_my_function;
    ....
    p->data = pp_my_function;

    or, more simply:

    function p_my_function = &my_function;
    ....
    p->data = &p_my_function;
    Philip Lantz, Sep 7, 2012
    #19
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    3
    Views:
    14,777
  2. Replies:
    7
    Views:
    591
    Victor Bazarov
    May 9, 2005
  3. jimjim
    Replies:
    28
    Views:
    868
    Michael Wojcik
    Apr 14, 2004
  4. Daniel Pitts
    Replies:
    7
    Views:
    462
  5. Replies:
    5
    Views:
    545
    James Kuyper
    May 25, 2009
Loading...

Share This Page