简体   繁体   中英

In C, what is the difference between `&function` and `function` when passed as arguments?

For example:

#include <stdio.h>

typedef void (* proto_1)();
typedef void proto_2();

void my_function(int j){
    printf("hello from function. I got %d.\n",j);
}

void call_arg_1(proto_1 arg){
    arg(5);
}
void call_arg_2(proto_2 arg){
    arg(5);
}
void main(){
    call_arg_1(&my_function);
    call_arg_1(my_function);
    call_arg_2(&my_function);
    call_arg_2(my_function);
}

Running this I get the following:

> tcc -run try.c
hello from function. I got 5.
hello from function. I got 5.
hello from function. I got 5.
hello from function. I got 5.

My two questions are:

  • What is the difference between a function prototype defined with (* proto) and one defined without?
  • What is the difference between calling a function with the reference operator ( & ) and without?

There is no difference. For evidence see the C99 specification (section 6.7.5.3.8).

"A declaration of a parameter as ''function returning type'' shall be adjusted to ''pointer to function returning type'', as in 6.3.2.1."

there is no difference between &function and function when passing as arguement

however there is a difference between your typedefs. I do not know the official explanation, ie what exactly the difference, but from what i remember

typedef void (*name1)(void);

and

typedef void(name2)(void);

are different:

name1 is a pointer to a function that takes no paramter and returns nothing

name2 is a function that takes no paramter and returns nothing

you can test it by compiling:

typedef void (*pointer)(void);
typedef void (function)(void);

void foo(void){}

int main()
{
    pointer p;
    function f;

    p = foo; //compiles
    p();

    f = foo; //does not compile
    f();
}

again, i am not the right person to explain exact reason of this behavior but i believe if you take a look at standards you will find the explanation somewhere there

There is no difference between &function and function - they're both addresses. You can see this by printing them both:

function bar(); 

.... 
printf("addr bar is 0x%d\n", &bar);
printf("bar is 0x%d\n", bar);

The difference is only stylistic. You have the same scenario when using function pointers:

void func (void);

...

void(*func_ptr)(void) = func;

func_ptr();    // call func
(*func_ptr)(); // call func

printf("%d\n", ptr); 
printf("%d\n", *ptr);

There are some who say that the (*func_ptr)() syntax is to prefer, to make it clear that the function call is done through a function pointer. Others believe that the style with the * is clearer.

As usual, there are likely no scientific studies proving that either form is better than the other, so just pick one style and stick to it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM