5

Can someone help me figure this declaration out?

int *x()(int)
void (*signal(int, void (*fp)(int)))(int)

I can't seem to parse these using methods given here . I know what this means using cdecl.org and also that the 1st one is illegal but I want to figure out how to parse these?

Rodrigo de Azevedo
  • 1,097
  • 9
  • 17
  • 1
    Check [this answer](https://stackoverflow.com/a/30345939/4265352). It explains pretty well (in my opinion) how to read the C declarations. – axiac Aug 13 '18 at 10:50
  • The first declaration would be a function that returns a pointer to an `int` but it has an extra `(int)` that makes it invalid. If you need a function that returns a pointer to a function that accepts an `int` as argument and returns an `int` then you need to wrap the *"function that returns a pointer"* part into parentheses: `int (*x())(int)`. Or you better declare the *"pointer to a function that accepts an `int` and returns an `int`"* as a new type (`T`) and turn `x` into a function that returns a value of this new type: `typedef int (*T)(int); T x();` – axiac Aug 13 '18 at 10:53
  • [This answer](https://stackoverflow.com/a/34560439/2455888) can help you to understand in deciphering such confusing pointer declarations. – haccks Aug 13 '18 at 11:04
  • All you need is contained in _Expert C Programming: Deep C Secrets_ Chapter 3 – haolee Aug 13 '18 at 11:19

2 Answers2

11

First, some basic rules:

T   *a[N];   // a is an array of pointer to T
T (*a)[N];   // a is a pointer to an array of T
T    *f();   // f is a function returning a pointer to T
T  (*f)();   // f is a pointer to a function returning T
const T *p;  // p is a non-const pointer to const T
T const *p;  // same as above
T * const p; // p is a const pointer to non-const T

In both declarators and expressions, the [] and () operators have higher precedence than the * operator, so you need to explicitly group it with the identifier when working with pointers to arrays ((*a)[N]) and pointers to functions ((*f)()).

When you find a hairy declaration, find the left-most identifier and work your way out, remembering the rules above, and applying them recursively to any function parameters:

       signal                               -- signal
       signal(                    )         -- is a function taking
       signal(                    )         --   parameter unnamed
       signal(int,                )         --     of type int
       signal(int,        fp      )         --   parameter fp
       signal(int,      (*fp)     )         --     is a pointer
       signal(int,      (*fp)(   ))         --     to a function taking
       signal(int,      (*fp)(   ))         --       parameter unnamed
       signal(int,      (*fp)(int))         --       of type int 
       signal(int, void (*fp)(int))         --     returning void
     (*signal(int, void (*fp)(int)))        -- returning a pointer
     (*signal(int, void (*fp)(int)))(   )   --   to a function taking
     (*signal(int, void (*fp)(int)))(   )   --     parameter unnamed
     (*signal(int, void (*fp)(int)))(int)   --     of type int
void (*signal(int, void (*fp)(int)))(int);  --   returning void

In English, signal is a function that takes an integer and a pointer to a signal function as parameters and returns a pointer to a handling function.

Occasionally you don't have an identifier (as in a function prototype where only the types are specified), so you have to mentally put in a placeholder (call it λ) and apply the rules to that placeholder:

void (*signal(int λ, void (*fp)(int λ)))(int λ);

John Bode
  • 119,563
  • 19
  • 122
  • 198
2

When function returns function pointer, return value surrounds the function name and it's arguments. So it helps to start from the center.

But best way to parse function pointer syntax is not have to parse it at all.

Second example can be written using typedef as:

typedef void funType(int);             // Our function type
funType * signal(int i, funType * fp); // Sane version of the function declaration

When you need to use function pointers, always define the function type first with the typedef.

user694733
  • 15,208
  • 2
  • 42
  • 68