"Int main (vooid)"? Як це працює?


135

Нещодавно мені довелося набрати невелику програму тестування на С, і під час цього я зробив орфографічну помилку в основній функції, випадково використовуючи vooidзамість void.

І все-таки це все працювало.

Зменшивши його до найменшої повної версії, я закінчив:

int main (vooid) {
    return 42;
}

Це дійсно компілюється ( gcc -Wall -o myprog myprog.c), і при запуску повертається 42.

Як саме цей дійсний код?


Ось вирізана стенограма і вклеєна з моєї bashоболонки, щоб показати, що я роблю:

pax$ cat qq.c
int main (vooid) {
    return 42;
}

pax$ rm qq ; gcc -Wall -o qq qq.c ; ./qq

pax$ echo $?
42

Визначаючи головний за допомогою одного intпараметра, ви викликаєте Невизначена поведінка . Будь-що може статися :)
pmg

9
Насправді, я не впевнений в UB, @pmg. ISO спеціально передбачає інші можливості mainвід стандартних двох канонічних. Для портативності вам слід використовувати один із цих двох, але я не думаю, що тут застосовується UB.
paxdiablo

Хм: у розміщеному середовищі mainмає бути одна з 2-х канонічних форм (2.1.2.2). Але ви маєте рацію @pax, у вільно стоячому середовищі ідентифікатор аж mainніяк не особливий: якщо він використовується як функція, він може бути будь-якого типу та мати будь-яку кількість параметрів будь-якого типу.
pmg

2
У C99, автономне встановлення повністю визначено. Для розміщених у розділі 5.1.2.2.1 наприкінці зазначено "або яким-небудь іншим способом, визначеним реалізацією", тому він вимагає, як мінімум, двох канонічних форм, але може мати й інші (це дозволило б UNIXy int main (int argc, char *argv[], char *envp[]);відповідати ).
paxdiablo

Відповіді:


220

Це просто використання синтаксису функції «декларування в старому стилі»; ви неявно оголошуєте intпараметр, який називається vooid.


2
Це, мабуть, так і є. Якщо ви додали "vooid = 42; повернути vooid;" до основного, ви також отримуєте зворотну вартість 42.
Джефф Еймс

43
Аарг, ти маєш рацію. Якщо додати -std=c99, я отримаю qq.c:1: warning: type of 'vooid' defaults to 'int'.
paxdiablo

70

Це дійсний код, оскільки myprog.c містить:

int main (vooid) // vooid is of type int, allowed, and an alias for argc
{     
  return 42; // The answer to the Ultimate Question
} 

vooidмістить один плюс кількість переданих аргументів (тобто argc). Отже, насправді все, що ви зробили, - це перейменування argcна vooid.


11
Якщо ви робите "return vooid;" натомість він дійсно дає 1 + число. аргів.
Джефф Еймс

6
@Jeff, назва програми зараховується як аргументація, звідси + 1
Мартін Бекетт

23

В C типом за замовчуванням для аргументу функції є int. Отже, ваша програма трактує слово vooidяк int main(int vooid), що є абсолютно правильним кодом.


20

Це лише gcc -std=c89 -Wall -o qq qq.cі gcc -std=gnu89 -Wall -o qq qq.cне надсилайте попередження. Всі інші стандарти випускають попередження про неявному типі intдля vooid.

int main(chart)поводиться так само, як і він int main (vooid).

return vooid; повертає кількість аргументів командного рядка.

Я тестував gcc 4.4.5 на системі тестування Debian.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.