Valid Function Pointer Casting

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Michael B Allen

    #1

    Valid Function Pointer Casting

    I need a macro to compute an offset of an object relative to a base
    address. The problem is the object can sometimes be a function pointer
    with a base address of 0 but I don't know in advance that the object is
    a function. Can it be done?

    #define BREF(b,p) ((size_t)((p) ? (char *)(p) - (char *)(b) : 0))

    The following code demonstrates that strict c89 doesn't accept casting
    a pointer to a function to a pointer to char which makes my above code
    invalid.

    typedef int (*fn)(void);

    void
    test(fn f)
    {
    char *g = (char *)f;
    }
    int
    main(void)
    {
    test(main);
    return 0;
    }

    cc -std1 q.c
    cc: Info: q.c, line 6: In the initializer for g, "f" of type "pointer
    to function () returning void", is being converted to "pointer to char".
    Such a cast is not permitted by the standard. (nonstandcast)
    char *g = (char *)f;
    --------------------------^
  • Alex Fraser

    #2
    Re: Valid Function Pointer Casting

    "Michael B Allen" <mba2000@ioplex .com> wrote in message
    news:pan.2005.0 3.20.01.51.58.5 57980.26010@iop lex.com...[color=blue]
    > I need a macro to compute an offset of an object relative to a base
    > address. The problem is the object can sometimes be a function pointer
    > with a base address of 0 but I don't know in advance that the object is
    > a function. Can it be done?[/color]

    Not portably.
    [color=blue]
    > #define BREF(b,p) ((size_t)((p) ? (char *)(p) - (char *)(b) : 0))
    >
    > The following code demonstrates that strict c89 doesn't accept casting
    > a pointer to a function to a pointer to char which makes my above code
    > invalid.[/color]

    That's correct. Consider architectures where code and data are in seperate
    memory areas (eg many microcontroller s): such a conversion is nonsense.
    (Usually, if the cast isn't nonsense, it will do what you expect.)

    That may not be the only problem: when subtracting pointers, the result is
    only defined by the standard if the pointers point to elements of the same
    array or one past the last element of the array. (But, similarly, the result
    is often what you expect even if this requirement isn't met.)

    Alex


    Comment

    • Ed Vogel

      #3
      Re: Valid Function Pointer Casting


      "Michael B Allen" <mba2000@ioplex .com> wrote in message > cc -std1 q.c[color=blue]
      > cc: Info: q.c, line 6: In the initializer for g, "f" of type "pointer
      > to function () returning void", is being converted to "pointer to char".
      > Such a cast is not permitted by the standard. (nonstandcast)
      > char *g = (char *)f;
      > --------------------------^[/color]

      Note that the diagnostic output by the compiler is only
      an informational. There is still an object produced, and
      your program will run as expected. If you wish you can
      disable this diagnostic. One way to to do this is
      to add -msg_disable nonstandcast to the command line

      Ed Vogel
      DEC/Compaq/HP C/C++ Engineering


      Comment

      • Jack Klein

        #4
        Re: Valid Function Pointer Casting

        On Sun, 20 Mar 2005 01:51:59 -0500, Michael B Allen
        <mba2000@ioplex .com> wrote in comp.lang.c:
        [color=blue]
        > I need a macro to compute an offset of an object relative to a base
        > address. The problem is the object can sometimes be a function pointer
        > with a base address of 0 but I don't know in advance that the object is
        > a function. Can it be done?[/color]

        There is a flaw in your design or your reasoning. There can be no
        object that is relative to a function.
        [color=blue]
        > #define BREF(b,p) ((size_t)((p) ? (char *)(p) - (char *)(b) : 0))
        >
        > The following code demonstrates that strict c89 doesn't accept casting
        > a pointer to a function to a pointer to char which makes my above code
        > invalid.[/color]

        No version of the C standard has ever defined a conversion between any
        type of pointer to object and any type of pointer to function. They
        are not convertible, just as you can't convert a banana to a
        watermelon.

        This is despite the fact that several operating system interfaces
        (POSIX, Windows) define exactly that.
        [color=blue]
        > typedef int (*fn)(void);
        >
        > void
        > test(fn f)
        > {
        > char *g = (char *)f;
        > }
        > int
        > main(void)
        > {
        > test(main);
        > return 0;
        > }
        >
        > cc -std1 q.c
        > cc: Info: q.c, line 6: In the initializer for g, "f" of type "pointer
        > to function () returning void", is being converted to "pointer to char".
        > Such a cast is not permitted by the standard. (nonstandcast)
        > char *g = (char *)f;
        > --------------------------^[/color]

        You have two choices. The first is to ignore or disable the warning,
        which will work on some platforms but not all, for in some cases the
        pointers might literally have different sizes. The second is to
        reconsider your design and find a better way to implement it. If you
        tell us the underlying problem you are trying to solve, we might be
        able to help you with that.

        --
        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

        Working...