Ответ 1
Эта форма определения функции:
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) {}
объявление прямого параметра не имеет никакой цели, поскольку оно не используется ни в одном из реальных параметров, а определение функции fun
фактически эквивалентно:
void fun(int i) {}
Обратите внимание, что это расширение GNU C, и это не C. Компиляция с gcc
и -std=c99 -pedantic
даст ожидаемую диагностику:
предупреждение: ISO C запрещает форвардные объявления параметров [-pedantic]