次の C のコードが何をするのか理解しようとしています。
((void(*)())buf)();
ここで、「buf」はchar
配列です。
一歩ずつ進んでいきましょう。
void(*)()
これは、指定されていない引数を取り、戻り値を持たない関数へのポインターです。
(void(*)())buf
buf をこの関数ポインタ型にキャストするだけです。ついに、
((void(*)())buf)();
この関数を呼び出します。
したがって、ステートメント全体は「引数のない関数buf
へのポインターとして解釈し、void
その関数を呼び出す」です。
buf
タイプの関数ポインターvoid(*)()
(何も返さない/void を返し、未指定の引数を取る関数)にキャストして呼び出します。
ANSI 標準では、通常のデータ ポインターを関数ポインターにキャストすることは実際には許可されていませんが、プラットフォームでは許可されている場合があります。
気が遠くなるような宣言に出くわしたときは、「cdecl」コマンドを使用する傾向があります。例:
[me@machine]$ cdecl
Type `help' or `?' for help
cdecl> explain (void(*)())buf
cast buf into pointer to function returning void
「cdecl」の出力を説明するツールがあればいいのにと思う場合もありますが:/
これは、未指定のパラメーターを取り、何も返さない関数へのポインターでbuf
ある typeにキャストします。void (*)()
次に、そのアドレス (右端の 2 つの括弧) で関数を呼び出します。
buf
指定されていない引数を取り、それを呼び出す関数ポインターにキャストします。
((void(*)())buf)(); \------------/ `buf` をキャスト \---------/ type: 固定値を受け入れる関数へのポインター。 不特定数の引数と void を返す \----------------/ そしてその「関数」を呼び出します
「専門家の c プログラミング」は読みやすいかもしれません. 読んでからずいぶん経ちましたが、当時は苦労した甲斐があったと思いました。 http://www.amazon.com/Expert-Programming-Peter-van-Linden/dp/0131774298
lsc が言及した「cdecl」ツールのオンライン バージョンがあり、役に立つかもしれません: http://www.cdecl.org/
多くの状況で、マシンがクラッシュすると思います。それ以外の場合、配列は void を返し、それを呼び出す関数へのポインターとして扱われます。
関数ポインタを呼び出します。関数には引数がありません。