web-dev-qa-db-ja.com

名前付き引数を持つ関数ポインター?

最近、Cプログラムで奇妙な構文に遭遇しました。

struct connector_agent_api{
    bool (*receive)(slot *s, uint8_t *data, uint8_t length);
}

「受信」は関数ポインタですか?

関数ポインタの場合、なぜ名前付き引数があるのですか?次のようなものでしょうか?

bool (*receive)(slot *, uint8_t *, uint8_t);

それは確かにコンパイルされ、ライブラリで使用されています。私はインターネットでたくさん検索して、この種の構文を正当化しようとしました。なぜこれをコンパイルできるのかまだわかりません... :(

16
ZuckerReis

関数宣言の引数の名前がオプションであるのと同様に、関数ポインターの引数の名前はオプションです。これは、指定されたパラメーター名が使用されないため、両方の形式が許可されるためです。

関数プロトタイプと関数ポインターの両方を含む関数宣言子についての C標準 のセクション6.7.6.3で、パラグラフ6は次のように述べています。

パラメータタイプリストは、関数のパラメータのタイプを指定し、関数のパラメータの識別子を宣言できます。

関数パラメーターが名前を必要とする唯一の場所は、関数の実際の定義です。

関数定義については、セクション6.9.1p5に次のように記載されています。

宣言子にパラメーター型リストが含まれている場合、各パラメーターの宣言には識別子が含まれます。ただし、void型の単一パラメーターで構成されるパラメーターリストの特別な場合は除きます。この場合、識別子はありません。宣言リストは後に続きません。

18
dbush

何が奇妙な構文だと思いますか?これは、C標準による有効な宣言です。パラメータに名前が付けられているという事実は関係ありません。この場合、そのようなパラメーターの命名はオプションです。あなたまたは他の誰かがIDEを使用している場合は、関数ポインタを使用して関数を呼び出すときに完全なプロトタイプを表示し、引数に関するコーダーにヒントを与えることができるため、非常に役立ちます。供給される。

4
machine_1