web-dev-qa-db-ja.com

パラメータ転送宣言とは何ですか?

次のコードをコンパイルしようとするまで、Cの構文をよく知っていると思いました。

void f(int i; double x)
{
}

コンパイラーがトリップすることを期待しましたが、トリップしましたが、エラーメッセージは表示されません。

test.c:1:14: error: parameter ‘i’ has just a forward declaration

それから私は試しました

void fun(int i; i)
{
}

失敗する

test.c:1:17: error: expected declaration specifiers or ‘...’ before ‘i’

そして最後に

void fun(int i; int i)
{
}

驚いたことに、これは成功しました!

この構文は実際のCコードでは見たことがありません。その用途は何ですか?

32
Fred Foo

この形式の関数定義:

void fun(int i; int i)
{
}

GNU C拡張機能と呼ばれるパラメータ転送宣言機能を使用)。

http://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html

この機能により、パラメーターの実際のリストの前にパラメーターの前方宣言を行うことができます。これは、たとえば、可変長配列パラメーターを持つ関数で、可変長配列パラメーターの後にサイズパラメーターを宣言するために使用できます。

例えば:

// valid, len parameter is used after its declaration 
void foo(int len, char data[len][len]) {}  

// not valid, len parameter is used before its declaration
void foo(char data[len][len], int len) {}

// valid in GNU C, there is a forward declaration of len parameter
// Note: foo is also function with two parameters
void foo(int len; char data[len][len], int len) {}  

OPの例では、

void fun(int i; int i) {}

forwardパラメーター宣言は、実際のパラメーターのいずれでも使用されておらず、fun関数定義は実際には次のものと同等であるため、何の目的も果たしません。

void fun(int i) {}

これはGNU C拡張であり、Cではないことに注意してください。gccand -std=c99 -pedanticを使用してコンパイルすると、予期される診断が得られます。

警告:ISO Cは前方パラメータ宣言を禁止します[-pedantic]

29
ouah