色々な関数宣言の練習

ちょっと仕事で宣言からtypedefで宣言された型名を調べる必要があって、構文解析の真似事が必要になったので。


// int を返す関数へのポインタを返す関数へのポインタ
int (*(*pf)())();

int ff() { return 0; }
int (*f())() { return ff; }

pf = f;

// int を返す関数へのポインタの3要素配列への参照を返す関数へのポインタ
int (*(&(*pg)())[3])();

// int を返す関数へのポインタの3要素配列
typedef int (*funcArray[3])();

int g0() { return 1; }

funcArray ar = {g0, g0, g0};

int (*(&g())[3])() { return ar; }

pg = g;

一番外側の左から順に読んでいけば分かりやすいか。

int X; // int
int X(); // を返す関数
int (*X)(); // へのポインタ
int (*X[3])(); // の3要素配列
int (*(&X)[3])(); // への参照
int (*(&X())[3])(); // を返す関数
int (*(&(*X)())[3])(); // へのポインタ

  • 括弧の外側から読む
  • 宣言している識別子の左にある修飾のほうが結合が弱いから、先に読む

というシンプルなルールで読める。でも全部前置にして、
int()*[3]&()* f;
とかの方がよっぽど読みやすい。

C/C++の宣言構文は実に恐ろしい。