How typedef works for function pointers

后端 未结 4 1108
名媛妹妹
名媛妹妹 2020-11-29 07:54

I think I may be suffering from the dreaded \"accidental programmer\" disease, at least when it comes to typedefs and function pointers. So I\'ve been experimenting with all

相关标签:
4条回答
  • 2020-11-29 08:16

    It turns out that, in C/C++, both funcname and &funcname will yield the address of funcname and can be assigned to a function pointer variable. This is actually just an oddity of how the syntax was designed for the language(s).

    0 讨论(0)
  • 2020-11-29 08:17

    The thing about function pointers is that they're function pointers! :-) This is how you get your third sample to work:

    #include <stdio.h>
    typedef void (*print)(void);
    //            ^
    void do_something (void) { printf("Hello World\n"); }
    int main (void) {
        print pr;
        pr = do_something; // &do_something would also work.
        pr();
        return 0;
    }
    

    In terms of whether you use funcName or &funcName, it doesn't matter (in C at least). Section 6.3.2.1 Lvalues, arrays and function designators states:

    A function designator is an expression that has function type. Except when it is the operand of the sizeof operator or the unary & operator, a function designator with type "function returning type" is converted to an expression that has type "pointer to function returning type".

    0 讨论(0)
  • 2020-11-29 08:30

    The address of a function name and the plain function name both mean the same thing, so & has no effect on a function name.

    Similarly, when using function pointers, multiple dereferencing isn't a problem:

    #include <stdio.h>
    typedef void print(void);
    static void dosomething(void) { printf("Hello World\n"); }
    
    int main(void)
    {
        print *f1 = dosomething;
        print *f2 = &dosomething;
        f2();
        (f1)();
        (*f1)();
        (**f2)();
        (***f1)();
        (****f2)();
        (*****f1)();
    }
    

    That compiles cleanly under:

    gcc -O3 -g -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes \
        -Wold-style-definition -std=c99 xx.c -o xx
    

    I would not claim that multiple stars is good style; it isn't. It is 'odd, and (yes, you may say it) perverse'. One is sufficient (and the one star is mainly for people like me who learned to program in C before the standard said "it is OK to call a function via a pointer without using the (*pointer_to_function)(arg1, arg2) notation; you can just write pointer_to_function(arg1, arg2) if you like"). Yes, it is weird. No, no other type (or class of types) exhibits the same behaviour, thank goodness.

    0 讨论(0)
  • 2020-11-29 08:32

    Like C, C++ has pointer to functions: void (*)() for example is a pointer to a function that takes no argument and returns no value. However, C++ has also introduced references to functions void (&)() and there are implicit conversions between the two (though I don't remember the rules exactly).

    Therefore:

    • funcname is a reference to function
    • &funcname is a pointer to function

    Note that taking the address (or a reference to) a function that is overloaded requires a static_cast to the exact type (to resolve the overload).

    0 讨论(0)
提交回复
热议问题