0

I'm writing this C code that involves passing around a lot of function pointers, and sometimes writing all the arguments that a function pointer takes when defining a function that takes it as an argument can significantly increase the length of the function definition and thus decrease its readability. For instance, say I have this function foo that takes three ints and a function pointer to perform a certain operation. The typical way to declare a function like foo is something along the lines of:

int foo(int a, int b, int c, int (*operation) (int, int, int));

I was wondering if there was a way to avoid the redundancy of having to re-mention the variable types another time in the type of the function pointer.

An answer to this question suggests that it is possible to only use empty parentheses () , which translates in the above example to:

int foo(int a, int b, int c, int (*operation) ());

However, a comment to the same post states that this kind of syntax is going to be removed in C23:

As a side note, this is obsolescent C since year 1989. Empty parenthesis () no prototype style should not be used. And it will finally get removed in upcoming C23

Mehdi Charife
  • 722
  • 1
  • 7
  • 22
  • 2
    Use a `typedef`. – Barmar Jun 27 '23 at 08:59
  • @KamilCuk In this example maybe, but imagine if `operation` also took a function pointer as an argument. This is the kind of stuff I'm dealing with mostly. – Mehdi Charife Jun 27 '23 at 08:59
  • 1
    https://stackoverflow.com/questions/11038430/how-to-create-a-typedef-for-function-pointers – Mat Jun 27 '23 at 08:59
  • 1
    Actually, in C23 a function declared with an empty parameter type list is the same as a function declared with a parameter type list consisting solely of the keyword `void`, i.e. in C23, `int foo()` and `int foo(void)` are the same. This is a deviation from previous versions of the C standard in the case where the function declarator is not part of a function definition. – Ian Abbott Jun 27 '23 at 09:47
  • @IanAbbott So it will not be removed, just have its behaviour/meaning change? – Mehdi Charife Jun 27 '23 at 10:15
  • 1
    Yes, its behavior/meaning will be aligned with C++. In current (pre-C23), `int foo();` declares a function with no information about parameters, but in C23 is will declare a function with no parameters (same as `int foo(void);`). In a function definition, `int foo() { return 42; }` is the same as `int foo(void) { return 42; }` in both pre-C23 and C23. – Ian Abbott Jun 27 '23 at 10:23
  • 1
    Also, pre-C23, `int foo();` and `int foo(int, int, int);` are compatible with each other, but in C23 they will no longer be compatible with each other. – Ian Abbott Jun 27 '23 at 10:28
  • 1
    The correct solution before or after C23 is to always use `typedef` for all function pointer types. – Lundin Jul 03 '23 at 08:26
  • @Lundin What's wrong with the solution that uses empty parentheses to declare a function pointer prior to C23? – Mehdi Charife Jul 03 '23 at 10:54

1 Answers1

6

So, just make an alias. I like function aliases over function pointer aliases, so that I know it's a pointer.

typedef int operation_t(int, int, int);
int foo(int a, int b, int c, operation_t *operation);
Barmar
  • 741,623
  • 53
  • 500
  • 612
KamilCuk
  • 120,984
  • 8
  • 59
  • 111