私のプロジェクトソースファイルの1つで、次のC関数定義を見つけました。
int (foo) (int *bar)
{
return foo (bar);
}
注:foo
の横にはアスタリスクがないため、関数ポインターではありません。またはそれは?ここで再帰呼び出しで何が起こっていますか?
プリプロセッサの処理が行われていない場合、foo
の署名は次と同等です
_int foo (int *bar)
_
関数名の周りに一見不必要な括弧を付けている人々を見た唯一のコンテキストは、同じ名前の関数と関数のようなマクロの両方があり、プログラマがマクロの展開を防ぎたい場合です。
このプラクティスは最初は少し奇妙に思えるかもしれませんが、Cライブラリは マクロと関数を同じ名前で提供する によって先例を設定します。
そのような関数/マクロのペアの1つはisdigit()
です。ライブラリは次のように定義します。
_/* the macro */
#define isdigit(c) ...
/* the function */
int (isdigit)(int c) /* avoid the macro through the use of parentheses */
{
return isdigit(c); /* use the macro */
}
_
あなたの関数は上記とほとんど同じように見えるので、これはあなたのコードでも起こっていると思います。
Paranthesesは宣言を変更しません-まだfoo
と呼ばれる通常の関数を定義しているだけです。
foo
と呼ばれる関数のようなマクロが定義されているため、それらが使用された理由はほぼ確実です。
_#define foo(x) ...
_
関数宣言で_(foo)
_を使用すると、このマクロがここで展開されなくなります。そのため、おそらくfoo()
が定義され、その本体は関数のようなマクロfoo
から展開されます。