Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can `(*)` be omitted from a function pointer inside a function parameter list?

Tags:

c

Compiling with gcc8:

#include <stdio.h>
void some_func(void f1(void), void (*f2)(void))
{
    printf("%d\n", f1);
    printf("%d\n", f2);
}

Gives (only) the following warnings:

<source>:11:14: warning: format '%d' expects argument of type 'int', but argument 2 has type 'void (*)(void)' [-Wformat=]
     printf("%d\n", f1);
<source>:12:14: warning: format '%d' expects argument of type 'int', but argument 2 has type 'void (*)(void)' [-Wformat=]
     printf("%d\n", f2);

Why is the type of f1 the same as f2? Only f2 is declared as a function pointer. I would expect f1 not to compile at all, as it names a function type, not a function pointer. What is the rule that says, that a function type inside a function parameter list changes to a pointer to that function type?

like image 378
KamilCuk Avatar asked Oct 25 '18 19:10

KamilCuk


People also ask

How to pass the reference of a function as a parameter?

But we can pass the reference of a function as a parameter by using a function pointer. This process is known as call by reference as the function parameter is passed as a pointer that holds the address of arguments. If any change made by the function using pointers, then it will also reflect the changes at the address of the passed variable.

What is a function pointer?

Function pointers are similar, except that instead of pointing to variables, they point to functions! Consider the following function: Identifier foo is the function’s name. But what type is the function? Functions have their own l-value function type -- in this case, a function type that returns an integer and takes no parameters.

Can a function pointer be passed as an argument?

For example, in below program, user is asked for a choice between 0 and 2 to do different tasks. 6) Like normal data pointers, a function pointer can be passed as an argument and can also be returned from a function. For example, consider the following C program where wrapper () receives a void fun () as parameter and calls the passed function.

What is the difference between default parameters and function pointers?

One interesting note: Default parameters won’t work for functions called through function pointers. Default parameters are resolved at compile-time (that is, if you don’t supply an argument for a defaulted parameter, the compiler substitutes one in for you when the code is compiled). However, function pointers are resolved at run-time.


2 Answers

Because the standard (6.7.6.3p8) says that

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

It's similar to how arrays parameters are adjusted to pointers (6.7.63.p7) , if you think about it.

void some_func(void (void));
void some_func(void (*)(void));

are compatible declarations, just like:

void other_func(char string[]);
void other_func(char *string);

are.


Note that the adjustment doesn't make void some_func(void (*)(void) compatible with void some_other_func(void (**)(void) or void yet_another_func(void (*****)(void) and that as far as functions are concerned, declarations don't really reflect use anymore, (despite that being the intention of the language's original author). In standardized C, due to how function identifiers decay to pointers and due to how it doesn't matter whether you use a function type or a function pointer type to make a call, you can call any function with arbitrarily many *:

#include <stdio.h>
int main()
{
    (*puts)("hello world");
    (******puts)("hello world");
    (***&*&*puts)("hello world"); //& cancels a * as per 6.5.3.2p3

    int (*p)(char const*) = puts;
    int (**pp)(char const*) = &p;
    int (***ppp)(char const*) = &pp;

    (**ppp)("hello world"); //at least two asterisks required here
}
like image 176
PSkocik Avatar answered Nov 15 '22 19:11

PSkocik


Because in C, in that case, the function name itself is a function pointer. See this answer: Why is using the function name as a function pointer equivalent to applying the address-of operator to the function name?

like image 45
ad3angel1s Avatar answered Nov 15 '22 19:11

ad3angel1s