3

I found this declaration in the APUE book in the chapter on signals:

void (*signal(int signo, void (*func)(int)))(int);

I don't fully understand the syntax. The declaration of (*func) is syntactically what I expect for a function parameter/pointer. I don't understand the syntax where "signal" is declared, and the trailing (int). I was wondering if someone could clarify this. -Thanks

  • `cdecl` can help you. Unfortunately finding the correct way to feed the type into `cdecl` is tricky – phuclv Jul 30 '22 at 02:21

2 Answers2

1

The function signal returns a pointer to a function of type void (int), and has two arguments: an int and a pointer to a function of type void (int).

So something like this should work

void foo(int);

void (*signal(int signo, void (*func)(int)))(int)
{
    return func;
}

int main(int argc, char *argv[])
{
    signal(42, foo);

    return 0;
}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
beothunder
  • 551
  • 2
  • 14
0

Use spiral rule (reading inside out clockwise) to understand the syntax:

  1. Find the identifier

     void (*signal(int signo, void (*func)(int)))(int);
            ^    ^
            |    |
            +----+
              |
           Identifier name
    

signal is a ....

  1. Move right

     void (*signal(int signo, void (*func)(int)))(int);
                  ^                            ^
                  |                            |
                  +----------------------------+
                                 |
                             arguments (so, its a function)
    

signal is a function which accepts int and void (*) (int) [pointer to a function which accepts a int argument and returns nothing (void)] as arguments ....

  1. Can't move right anymore because of the right parenthesis, so move left.

     void (*signal(int signo, void (*func)(int)))(int);
           ^
           |
        pointer
    

signal is a function which accepts int and void (*) (int) as arguments and returns a pointer ....

  1. Can't move left anymore because of the left parenthesis, so keep going right.

     void (*signal(int signo, void (*func)(int)))(int);
                                                 ^   ^
                                                 |   |
                                                 +---+
                                                   |
                                                argument 
                       (which means signal() is returning a function pointer)
    

signal is a function which accepts int and void (*) (int) as arguments and returns a pointer to a function which accepts a int argument and ....

  1. Can't move right anymore because we're out of symbols, so go left.

     void (*signal(int signo, void (*func)(int)))(int);
     ^  ^
     |  |
     +--+
       |
     return type of function whose pointer returned by signal() function
    

signal is a function which accepts int and void (*) (int) as arguments and returns a pointer to function which accepts a int argument and returns nothing (void).

H.S.
  • 11,654
  • 2
  • 15
  • 32