"Int main (vooid)"? Wie funktioniert das?


135

Ich musste kürzlich ein kleines C-Testprogramm eingeben und habe dabei einen Rechtschreibfehler in der Hauptfunktion gemacht, indem ich versehentlich vooidanstelle von verwendet habe void.

Und trotzdem hat es funktioniert.

Als ich es auf die kleinste vollständige Version reduzierte, endete ich mit:

int main (vooid) {
    return 42;
}

Dies kompiliert tatsächlich ( gcc -Wall -o myprog myprog.c) und gibt beim Ausführen 42 zurück.

Wie genau ist dieser gültige Code?


Hier ist ein Transkript, das aus meiner bashShell ausgeschnitten und eingefügt wurde, um zu zeigen, was ich tue:

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

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

pax$ echo $?
42

Indem Sie main mit einem einzelnen intParameter definieren, rufen Sie Undefined Behavior auf . Alles kann passieren :)
pmg

9
Eigentlich bin ich mir nicht sicher über die UB, @pmg. ISO erlaubt speziell andere Möglichkeiten mainvon den Standard zwei kanonischen. Für die Portabilität sollten Sie eine dieser beiden verwenden, aber ich denke nicht, dass UB hier gilt.
Paxdiablo

Hmm: In einer gehosteten Umgebung mainmuss eine der beiden kanonischen Formen vorliegen (2.1.2.2). Aber Sie haben Recht @pax, in einer freistehenden Umgebung ist der Bezeichner mainin keiner Weise speziell: Wenn er als Funktion verwendet wird, kann er von einem beliebigen Typ sein und eine beliebige Anzahl von Parametern eines beliebigen Typs haben.
PMG

2
In C99 ist freistehend vollständig implementierungsdefiniert. Für gehostete, Abschnitt 5.1.2.2.1 Staaten am Ende „oder in einer anderen Implementierung definiert Art und Weise“ , so dass es, auf ein Minimum erfordert, die beiden kanonischen Formen können aber auch andere haben (dies ist der Unixy erlauben würde , int main (int argc, char *argv[], char *envp[]);konform zu sein ).
Paxdiablo

Antworten:


220

Es wird einfach die Syntax der Funktionsdeklaration im "alten Stil" verwendet. Sie deklarieren implizit einen intParameter namens vooid.


2
Dies scheint der Fall zu sein. Wenn Sie "vooid = 42; return vooid;" zu main erhalten Sie auch einen Rückgabewert von 42.
Jeff Ames

43
Aargghh, du hast recht. Wenn ich hinzufüge -std=c99, bekomme ich qq.c:1: warning: type of 'vooid' defaults to 'int'.
Paxdiablo

70

Es ist ein gültiger Code, da myprog.c Folgendes enthält:

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

vooidenthält eins plus die Anzahl der übergebenen Argumente (dh argc). Also in der Tat alles , was Sie getan haben , ist zu umbenennen argczu vooid.


11
Wenn Sie "void zurückgeben"; stattdessen gibt es tatsächlich 1 + num. von args.
Jeff Ames

6
@ Jeff, der Name des Programms wird als Argument gezählt, daher die + 1
Martin Beckett

23

In C ist der Standardtyp für ein Funktionsargument int. Ihr Programm behandelt das Wort also vooidals einen int main(int vooid)vollkommen gültigen Code.


20

Es ist nur gcc -std=c89 -Wall -o qq qq.cund gcc -std=gnu89 -Wall -o qq qq.ckeine Warnung ausgeben. Alle anderen Standards geben eine Warnung über den impliziten Typ intfür aus vooid.

int main(chart)verhält sich genauso wie int main (vooid).

return vooid; Gibt die Anzahl der Befehlszeilenargumente zurück.

Ich habe mit gcc 4.4.5 auf dem Debian-Testsystem getestet.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.