宣言

まぁ、普通は typedef 使え、ってな話だよね。signal の宣言なんか typedef 使わないとひどい。

/* with typedef */
typedef void (*sighandler_t)(int);
signalder_t signal(int signo, sighandler_t handler);

/* without typedef */
void (*signal(int signo, void (*handler)(int)))(int);

ちなみに、宣言文と英語を相互変換してくれる Web サイトとかあったりする(ただし、仮引数の名前は書けない)。

変換プログラム自体も公開されている。

% wget http://cdecl.org/files/cdecl-blocks-2.5.tar.gz
% tar zxf cdecl-blocks-2.5.tar.gz
% make
yacc cdgram.y && mv y.tab.c cdgram.c
lex cdlex.l && mv lex.yy.c cdlex.c
gcc -g -O2 -o c++decl cdecl.c 
rm -f cdecl
ln -s c++decl cdecl
% ./cdecl
Type `help' or `?' for help
cdecl> explain void (*signal(int, void (*)(int)))(int)
declare signal as function (int, pointer to function (int) returning void) returning pointer to function (int) returning void
cdecl> exit

あと、C++ だとメンバへのポインタもあるのでさらにややこしいとか、const/volatile もあるよ、とかいう話も。

% ./c++decl
Type `help' or `?' for help
c++decl> explain int X::*x
declare x as pointer to member of class X int
c++decl> explain int (X::*x)(int)
declare x as pointer to member of class X function (int) returning int
c++decl> explain const int *p
declare p as pointer to const int
c++decl> explain int * const p
declare p as const pointer to int
c++decl> exit

追記1

sighandler_t の宣言を間違えていたので修正。