1

関数ポインターの例であり、Linuxカーネルソースから取得したコードがあります。以下は、メンバーとしてコールバック関数を持つ構造です

 struct parport_driver {
 const char *name;
 void (*attach) (struct parport *);
 struct parport_driver *next;
 };

これらの構造体のメンバーは、以下のように C ファイルで呼び出されます

 struct parport_driver *drv;

 drv->attach(port); /* calling function through implicit dereference */

上記の関数は暗黙的な方法で呼び出されますが、明示的な方法でどのように呼び出されるか知りたいです。

関数ポインタを逆参照する暗黙的方法と明示的方法の違いは何ですか。

もう1つ知りたいことは、呼び出しの前に構造体メンバーのアタッチを初期化する必要があることです (drv->attach(port));

みたいな

drv->attach=attach_driver_chain;

どこで attach_driver_chain は関数ですが、ドライバーコードでそのような初期化を見つけることができませんでした。

4

3 に答える 3

7

後置()演算子 (関数呼び出し) は、関数へのポインターを取り、関数を呼び出すように定義されています。したがって、これはポインターの明示的な逆参照です。関数を呼び出す他の方法はありません。

明示的(*FunctionPointer)()な逆参照のように見えますが、式の型は*FunctionPointer関数です。C 2011 6.3.2.1 4 に従って、関数型の式は関数へのポインターに変換されます (式がsizeof_Alignof、またはのオペランドである場合を除く&)。そのため、 in(*FunctionPointer)()*FunctionPointerと同じに変換されFunctionPointer、何も実行されていません。式は以前と同じであり、()演算子は関数ではなく関数ポインターに作用します。

FunctionPointer()で関数を呼び出す場合と で呼び出す場合に違いはありません(*FunctionPointer)()(***************FunctionPointer)()同じ効果で書くことさえできます。各*演算子は、自動変換によって無効化されます。

于 2013-06-26T13:25:19.583 に答える
4

上記の関数は暗黙的な方法で呼び出されますが、明示的な方法でどのように呼び出されるかを知りたいと思っていました。

このような:

(*(drv->attach))(port); // Not very pretty, huh?

関数ポインタを逆参照する暗黙的方法と明示的方法の違いは何ですか

違いはありません。関数ポインターでできることは、それが指す関数を呼び出すことだけなので、コンパイラーは関数ポインターの明示的な逆参照を無視します。

于 2013-06-26T10:40:06.530 に答える