web-dev-qa-db-ja.com

関数名を囲む括弧は何を意味しますか?

私のプロジェクトソースファイルの1つで、次のC関数定義を見つけました。

int (foo) (int *bar)
{
    return foo (bar);
}

注:fooの横にはアスタリスクがないため、関数ポインターではありません。またはそれは?ここで再帰呼び出しで何が起こっていますか?

213
user1859094

プリプロセッサの処理が行われていない場合、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 */
}
_

あなたの関数は上記とほとんど同じように見えるので、これはあなたのコードでも起こっていると思います。

329
NPE

Paranthesesは宣言を変更しません-まだfooと呼ばれる通常の関数を定義しているだけです。

fooと呼ばれる関数のようなマクロが定義されているため、それらが使用された理由はほぼ確実です。

_#define foo(x) ...
_

関数宣言で_(foo)_を使用すると、このマクロがここで展開されなくなります。そのため、おそらくfoo()が定義され、その本体は関数のようなマクロfooから展開されます。

37
caf