2013-12-19 22 views
4

Я просто пытаюсь понять этот код C (не пытаясь достичь какой-либо функциональной цели программой). Это компилируется с использованием gcc. Является ли это основным в main (int a, char * argv []) формат? Допустимо ли объявлять что-либо из аргумента и тела функции (аналогично char * a; здесь)?Почему программа компилируется?

#include <stdio.h> 
main(u,_,a) 
    char 
    *a; 
{ 
    //printf("%s\n",_,a);//just to help debugging 
    //printf("%d\n",u); //just to help debugging 
} 
+1

Похоже функции стиля до C89. – chux

+1

Чтобы добавить забавный факт, который не заслуживает ответа: мне пришлось использовать этот стиль деклараций функций при написании 16-битной загрузочной программы. gcc не компилируется в 16 бит, поэтому мне пришлось использовать bcc (компилятор Bruce's C), который не поддерживает ANSI. Таким образом, вы можете столкнуться с этим материалом в некоторых областях! – Guido

ответ

4

Это старый, устаревший способ написания функций C.

На языке предков C не было типов: все переменные содержали машинное слово. Таким образом, определение функции будет начать так:

main(u, _, a) { 
    /* ... some code ... */ 
} 

C as it used to be, известный как «K & RC» от ​​авторов seminal book about C (Brian Керниган и Деннис Ритчи) добавлены типы в виде, похожем объявления переменных и были между списком параметров функции и кодом функции.

int main(u, _, a) 
    int u; 
    int _; 
    char *a; 
{ 
    /* ... some code ... */ 
} 

В K & R C, если тип является int, то во многих местах он может быть опущен. Для параметра функции вы можете вообще опустить строку объявления типа.

int main(u, _, a) 
    char *a; 
{ 
    /* ... some code ... */ 
} 

ANSI C был стандартизирован в 1989 году, и одна из его главных новшеств были прототипами функций. В правильном ANSI C вы объявляете все функции перед использованием и объявляете типы всех аргументов.

int main(int u, int _, char *a) 
{ 
    /* ... some code ... */ 
} 

Компиляторы C по-прежнему поддерживают старую форму для устаревшего кода. (Если они соответствуют стандарту 1989 C, они должны это делать.) После более чем 20 лет осталось много устаревшего кода, поэтому вы часто не найдете такой код.

(Обратите внимание, что это не правильный тип для main. Я думаю, что Gcc предупредит вас об этом, но вы, возможно, придется включить настройки предупреждения вверх.)

-1

Это недопустимая форма объявления main. Это неверно в C99/C11, но также недействительно на C90. (См. 5.1.2.2.1 для действительных объявлений функции main в C90).

+0

Итак, ответ на вопрос «почему он все же скомпилирован» является «потому что GCC является чрезмерно разрешительным». –

+0

@ H2CO3 как обычно – ouah

+0

Хотя технически это правда, это очень бесполезно и не отвечает на вопрос, почему компилятор примет такой недействительный код. – Gilles

3

Это старая декларация, которую никто больше не использует, кроме обфускации (см. Также: триграммы!). Я думаю, что это незаконно в соответствии с новыми стандартами C, но gcc все еще поддерживает его для обратной совместимости.

Способ, которым он работает, относится к типам, указанным в функции, и тип возврата оставлен. Тип возврата не имеет значения по умолчанию: int. Типичная основная функция может быть записана следующим образом:

main(argc, argv) 
    int argc; 
    char** argv; 
{ 
    printf("%d\n", argc); 
    return 0; 
} 

Вы не можете объявить другие переменные перед открывающей скобой. Попробуйте добавить int c; и получить эту ошибку:

test.c:4: error: declaration for parameter ‘c’ but no such parameter 
4

декларации между списком аргументов и функции тела были частью так называемой K & R C (первая версия C). Так что да, они действительны, если ваш компилятор может скомпилировать код K & R.

О main(), имеющих более двух аргументов ... да, на самом деле, главный могут иметь до трех аргументов:

int main (int argc, char *argv[], char *envp[]); 

Третьего аргумент является массивом указателей на строки, содержащий каждый из них определение переменной среды (строка в форме name=value)

Смежные вопросы