3

I am confused about following C function, f_2(). It is written in .c file, code can be compiled by gcc. What is the name of this function style? How to interpret the meaning of this function? Is this standard C or some gcc extension? Thanks.

void f_1()
{
}

int (*f_2(void *param)) (int, void *) {
    return 0;
}

int main()
{
  f_2(NULL);
  return 0;
}
Dawn16
  • 140
  • 8

2 Answers2

13

The function f_2 takes a void * arguments, and returns a pointer to a function.

The pointer that f_2 returns is a pointer to a function that takes two arguments (an int and a void *) and returns an int.

It's equivalent to:

// Create a type-alias for a function pointer
typedef int (*function_pointer_type)(int, void *);

// Define a function that returns a pointer to a function
function_pointer_type f_2(void *)
{
    return NULL;
}
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • 7
    I do not remember ever having used function pointers without `typedef`'ing its type. The notation without typedef is so weird that I imagine it is confusing for most people, even experienced C programmers. – nielsen Aug 02 '23 at 08:39
  • 2
    with C23 one can simply write `typeof(int(int,void*)) * f2(void*)` – tstanisl Aug 02 '23 at 08:51
3

Parsing a C definition visually can be done using the spiral rule:

int (*f_2(void *param)) (int, void *) {
  • start for the identifier being defined, here f_2:

    f_2 is ...

  • read and spell the postfix operators from left to right: (void *param):

    f_2 is a function taking a void * argument named param returning...

  • when you hit an obstacle (), ;, ,, {...), go back to where you started parsing postfix operators and parse prefix operators right to left: here the is only a * so:

    f_2 is a function taking a void * argument named param returning a pointer to a...

  • you have parsed the parenthesized expression, so start again with its postfix and then prefix operators: (int, void *):

    (f_2 is a function taking a void * argument named param returning a pointer to a) function taking an int and a void * arguments returning...

  • back to the ( and parse the prefix operators: there is just the int return type, so the final phrase is:

    f_2 is a function taking a void * argument named param returning a pointer to a function taking an int and a void * arguments returning an int.

You may want to read this question and its answers too: C isn't that hard: void ( *( *f[] ) () ) ()

chqrlie
  • 131,814
  • 10
  • 121
  • 189
  • Upvoted for the detailed explanation of deciphering this declaration. The length and complexity of the explanation makes a strong case for the use of `typedef` to help the poor reader of the code. – nielsen Aug 02 '23 at 11:16