cast function pointer to void*

Discussion in 'C Programming' started by WaterWalk, Nov 22, 2006.

  1. WaterWalk

    WaterWalk Guest

    *Hope this thread doesn't violate this group's rule*

    I found the following code in the GNOME's glib-2.12 source:

    /* In gclosure.c */
    GClosure*
    g_cclosure_new (GCallback callback_func,
    gpointer user_data,
    GClosureNotify destroy_data)
    {
    ......
    /* ((GCClosure*) closure)->callback is of type gpointer */
    ((GCClosure*) closure)->callback = (gpointer) callback_func;
    }

    Here a GCallback is cast to a gpointer type. The definition of
    GCallback and gpointer are as follows:
    typedef void (*GCallback) (void); /* in gclosure.h */
    typedef void* gpointer; /* in gtypes.h */

    So the result is that a (void (*)(void)) is cast to (void*). However a
    search of this group and c99 standard indicates that casting a
    function pointer to a void pointer is undefined behavior. I wonder if
    the glib practice is preferable.
    WaterWalk, Nov 22, 2006
    #1
    1. Advertising

  2. WaterWalk wrote:
    > *Hope this thread doesn't violate this group's rule*
    >
    > I found the following code in the GNOME's glib-2.12 source:
    > [...]
    > So the result is that a (void (*)(void)) is cast to (void*). However a
    > search of this group and c99 standard indicates that casting a
    > function pointer to a void pointer is undefined behavior.


    It's a constraint violation, actually, meaning it might not compile, or
    if it does compile, the /entire/ program is outside of the scope of the
    C standard (even if the conversion would never actually be performed).

    > I wonder if
    > the glib practice is preferable.


    Preferable to what? There's simply no way in standard C to reliably
    convert function pointers to object pointers, so if there is a
    legitimate reason to do so (I don't know if there is a good reason
    here), it must be done using an implementation-specific extension.
    =?utf-8?B?SGFyYWxkIHZhbiBExLNr?=, Nov 22, 2006
    #2
    1. Advertising

  3. WaterWalk

    Richard Bos Guest

    "WaterWalk" <> wrote:

    > *Hope this thread doesn't violate this group's rule*


    The code is off-topic, but the question you ask about it - basically,
    _is_ this ISO C - is on-topic.

    > /* In gclosure.c */
    > GClosure*
    > g_cclosure_new (GCallback callback_func,
    > gpointer user_data,
    > GClosureNotify destroy_data)
    > {
    > ......
    > /* ((GCClosure*) closure)->callback is of type gpointer */
    > ((GCClosure*) closure)->callback = (gpointer) callback_func;
    > }
    >
    > Here a GCallback is cast to a gpointer type. The definition of
    > GCallback and gpointer are as follows:
    > typedef void (*GCallback) (void); /* in gclosure.h */
    > typedef void* gpointer; /* in gtypes.h */
    >
    > So the result is that a (void (*)(void)) is cast to (void*). However a
    > search of this group and c99 standard indicates that casting a
    > function pointer to a void pointer is undefined behavior. I wonder if
    > the glib practice is preferable.


    Yes, it's undefined behaviour; and therefore, no, it's not preferable.
    Nor is it necessary, since ISO C requires that all function pointer
    types can be converted to and from one another without loss of
    information.

    Richard
    Richard Bos, Nov 22, 2006
    #3
  4. Harald van Dijk wrote:
    > WaterWalk wrote:
    > > *Hope this thread doesn't violate this group's rule*
    > >
    > > I found the following code in the GNOME's glib-2.12 source:
    > > [...]
    > > So the result is that a (void (*)(void)) is cast to (void*). However a
    > > search of this group and c99 standard indicates that casting a
    > > function pointer to a void pointer is undefined behavior.

    >
    > It's a constraint violation, actually, meaning it might not compile, or
    > if it does compile, the /entire/ program is outside of the scope of the
    > C standard (even if the conversion would never actually be performed).


    Actually... I know it's treated as a constraint violation by multiple
    compilers, but I can't seem to find any wording in the standard that
    says so. I'd appreciate it if anyone could point it out.
    =?utf-8?B?SGFyYWxkIHZhbiBExLNr?=, Nov 22, 2006
    #4
  5. WaterWalk

    Jack Klein Guest

    On 22 Nov 2006 07:03:15 -0800, "WaterWalk" <> wrote
    in comp.lang.c:

    > *Hope this thread doesn't violate this group's rule*
    >
    > I found the following code in the GNOME's glib-2.12 source:
    >
    > /* In gclosure.c */
    > GClosure*
    > g_cclosure_new (GCallback callback_func,
    > gpointer user_data,
    > GClosureNotify destroy_data)
    > {
    > ......
    > /* ((GCClosure*) closure)->callback is of type gpointer */
    > ((GCClosure*) closure)->callback = (gpointer) callback_func;
    > }
    >
    > Here a GCallback is cast to a gpointer type. The definition of
    > GCallback and gpointer are as follows:
    > typedef void (*GCallback) (void); /* in gclosure.h */
    > typedef void* gpointer; /* in gtypes.h */
    >
    > So the result is that a (void (*)(void)) is cast to (void*). However a
    > search of this group and c99 standard indicates that casting a
    > function pointer to a void pointer is undefined behavior. I wonder if
    > the glib practice is preferable.


    Unfortunately, there is a lot of code that is based on the fact that
    on many implementations pointers to functions and pointers to void
    have the same size and number of value bits. It is, was, and always
    has been sloppy programming with no real justification whatsoever.

    This behavior is now required in both the Windows and POSIX APIs, for
    example.

    But I don't understand your question. You post one code sample which
    you state if from glib source, then ask is the glib practice is
    preferable. Preferable to what alternative?

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://c-faq.com/
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++
    http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
    Jack Klein, Nov 22, 2006
    #5
  6. WaterWalk

    Spoon Guest

    Jack Klein wrote:

    > Unfortunately, there is a lot of code that is based on the fact that
    > on many implementations pointers to functions and pointers to void
    > have the same size and number of value bits. It is, was, and always
    > has been sloppy programming with no real justification whatsoever.
    >
    > This behavior is now required in both the Windows and POSIX APIs, for
    > example.


    As far as I remember, on IA-64/Linux, object pointers are 64 bits wide
    while function pointers are 128 bits wide.

    cf. http://www.gelato.unsw.edu.au/archives/linux-ia64/0201/2679.html

    "On IA64 and PPC64 the function pointer does not reference the function
    itself, instead it points to a function descriptor. The function
    descriptor contains a pointer to the function code plus additional data
    such as a pointer to the global data to be used when the function is
    called. This is mandated by the architecture software ABI."
    Spoon, Nov 22, 2006
    #6
  7. In article <>,
    Jack Klein <> wrote:
    >On 22 Nov 2006 07:03:15 -0800, "WaterWalk", who's native language is probably not English, <> wrote
    >in comp.lang.c:

    ....
    >> So the result is that a (void (*)(void)) is cast to (void*). However a
    >> search of this group and c99 standard indicates that casting a
    >> function pointer to a void pointer is undefined behavior. I wonder if
    >> the glib practice is preferable.

    ....
    >But I don't understand your question. You post one code sample which
    >you state if from glib source, then ask is the glib practice is
    >preferable. Preferable to what alternative?


    I think that he was using "preferable" when he meant "desirable".

    Give the guy a break!
    Kenny McCormack, Nov 22, 2006
    #7
  8. Spoon <> writes:
    [...]
    > As far as I remember, on IA-64/Linux, object pointers are 64 bits wide
    > while function pointers are 128 bits wide.


    No, all pointers are 64 bits wide (at least on the IA-64/Linux system
    I use).

    > cf. http://www.gelato.unsw.edu.au/archives/linux-ia64/0201/2679.html
    >
    > "On IA64 and PPC64 the function pointer does not reference the function
    > itself, instead it points to a function descriptor. The function
    > descriptor contains a pointer to the function code plus additional data
    > such as a pointer to the global data to be used when the function is
    > called. This is mandated by the architecture software ABI."


    If a function pointer points to a descriptor, there's no reason for it
    to be bigger than an object pointer.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
    Keith Thompson, Nov 22, 2006
    #8
  9. WaterWalk

    WaterWalk Guest

    Kenny McCormack wrote:
    > In article <>,
    > Jack Klein <> wrote:
    > >On 22 Nov 2006 07:03:15 -0800, "WaterWalk", who's native language is probably not English, <> wrote
    > >in comp.lang.c:

    > ...
    > >> So the result is that a (void (*)(void)) is cast to (void*). However a
    > >> search of this group and c99 standard indicates that casting a
    > >> function pointer to a void pointer is undefined behavior. I wonder if
    > >> the glib practice is preferable.

    > ...
    > >But I don't understand your question. You post one code sample which
    > >you state if from glib source, then ask is the glib practice is
    > >preferable. Preferable to what alternative?

    >
    > I think that he was using "preferable" when he meant "desirable".
    >
    > Give the guy a break!


    Yes, I should have used "desirable" rather than "preferable". Sorry for
    this misuse of word.

    When I saw this code in glib, I was confused: Glib is a widely-used
    library. It's code must(at least I think) be reviewed thoroughly. Yet
    this cast I posted is undefined. I just don't understand why the glib
    developers use such an extension, since it's not necessary, as Richart
    Bos previously said.

    Hope this clarifies my question. :)
    WaterWalk, Nov 23, 2006
    #9
  10. WaterWalk

    Old Wolf Guest

    WaterWalk wrote:
    > When I saw this code in glib, I was confused: Glib is a widely-used
    > library. It's code must(at least I think) be reviewed thoroughly. Yet
    > this cast I posted is undefined. I just don't understand why the glib
    > developers use such an extension, since it's not necessary, as Richart
    > Bos previously said.


    Well, all of the systems that Glib runs on, support this extension.

    Probably what happened is that the Glib developers did not
    realise, or did not care, that it was non-standard. Perhaps
    you could post on a Glib mailing list; they might be able to
    explain exactly why they chose this route.
    Old Wolf, Nov 23, 2006
    #10
  11. "WaterWalk" <> writes:
    [...]
    >> In article <>,
    >> Jack Klein <> wrote:
    >> >On 22 Nov 2006 07:03:15 -0800, "WaterWalk", who's native language
    >> >is probably not English, <> wrote in
    >> >comp.lang.c:

    [...]
    >> >> So the result is that a (void (*)(void)) is cast to (void*). However a
    >> >> search of this group and c99 standard indicates that casting a
    >> >> function pointer to a void pointer is undefined behavior. I wonder if
    >> >> the glib practice is preferable.

    >> ...
    >> >But I don't understand your question. You post one code sample which
    >> >you state if from glib source, then ask is the glib practice is
    >> >preferable. Preferable to what alternative?

    [...]
    > Yes, I should have used "desirable" rather than "preferable". Sorry for
    > this misuse of word.
    >
    > When I saw this code in glib, I was confused: Glib is a widely-used
    > library. It's code must(at least I think) be reviewed thoroughly. Yet
    > this cast I posted is undefined. I just don't understand why the glib
    > developers use such an extension, since it's not necessary, as Richart
    > Bos previously said.


    I suspect that GLib is not intended to be completely portable to all
    possible conforming C implementations. As far as I know, *most* C
    compilers do support conversions between function pointers and void*.
    Possibly GLib is merely intended to be portable to just those
    compilers. (The phrase "as far as I know" may be assumed to imply a
    wealth of ignorance; there are plenty of C compilers I'm not familiar
    with.)

    But as you say, it probably wasn't necessary to use this particular
    extension; GLib could have used, say, void (*)(void) as a generic
    pointer-to-function type.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
    Keith Thompson, Nov 23, 2006
    #11
    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. Ollej Reemt
    Replies:
    7
    Views:
    499
    Jack Klein
    Apr 22, 2005
  2. Stig Brautaset

    `void **' revisited: void *pop(void **root)

    Stig Brautaset, Oct 25, 2003, in forum: C Programming
    Replies:
    15
    Views:
    775
    The Real OS/2 Guy
    Oct 28, 2003
  3. Replies:
    5
    Views:
    815
    S.Tobias
    Jul 22, 2005
  4. Hakirato
    Replies:
    4
    Views:
    859
    Alf P. Steinbach
    Oct 5, 2006
  5. Replies:
    1
    Views:
    392
    Victor Bazarov
    May 23, 2007
Loading...

Share This Page