222

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

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

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

4

3 に答える 3

338

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

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

于 2012-11-28T08:30:46.817 に答える
38

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

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

#define foo(x) ...

関数宣言で使用(foo)すると、このマクロがここで展開されなくなります。したがって、起こりそうなことは、関数foo()の本体が関数のようなマクロから展開された状態で関数が定義されていることfooです。

于 2012-11-28T08:34:20.957 に答える
-3

括弧は無意味です。
表示するコードは、無限の再帰に他なりません。

関数ポインタを定義するとき、何かを意味する奇妙な括弧が表示されることがあります。しかし、これはここでは当てはまりません。

于 2012-11-28T08:30:34.393 に答える