“int main (leer)”? Wie funktioniert das?

Lesezeit: 3 Minuten

Benutzeravatar von paxdiablo
paxdiablo

Ich musste neulich ein kleines C-Testprogramm eintippen und habe mir dabei versehentlich einen Rechtschreibfehler in der Main-Funktion gemacht vooid Anstatt von void.

Und trotzdem hat es funktioniert.

Als ich es auf die kleinste vollständige Version reduzierte, kam ich zu folgendem Ergebnis:

int main (vooid) {
    return 42;
}

Das macht in der Tat kompilieren (gcc -Wall -o myprog myprog.c) und gibt bei der Ausführung 42 zurück.

Wie genau ist dieser gültige Code?


Hier ist eine Abschrift, die von meinem ausgeschnitten und eingefügt wurde bash Shell, 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

  • Durch die Definition von main mit einem single int Parameter, rufen Sie auf Undefiniertes Verhalten. Alles kann passieren 🙂

    – pmg

    13. Februar 2011 um 23:40 Uhr

  • Eigentlich bin ich mir bei der UB nicht sicher, @pmg. ISO lässt ausdrücklich andere Möglichkeiten von zu main von den standardmäßigen zwei kanonischen. Für die Portabilität sollten Sie eines dieser beiden verwenden, aber ich glaube nicht, dass UB hier zutrifft.

    – paxdiablo

    14. Februar 2011 um 0:50 Uhr

  • Hmm: in einer gehosteten Umgebung main muss eine der 2 kanonischen Formen haben (2.1.2.2). Aber du hast recht @pax, in einer freistehenden Umgebung die Kennung main ist in keiner Weise besonders: Wenn es als Funktion verwendet wird, kann es von beliebigem Typ sein und eine beliebige Anzahl von Parametern beliebigen Typs haben.

    – pmg

    14. Februar 2011 um 19:08 Uhr

  • In C99 ist freistehend vollständig implementierungsdefiniert. Für gehostet heißt es in Abschnitt 5.1.2.2.1 am Ende „oder auf eine andere implementierungsdefinierte Weise“, sodass es mindestens die beiden kanonischen Formen erfordert, aber auch andere haben kann (dies würde dem UNIXy int main (int argc, char *argv[], char *envp[]); konform sein).

    – paxdiablo

    14. Februar 2011 um 23:27 Uhr

Benutzeravatar von Oliver Charlesworth
Oliver Charlesworth

Es wird einfach die Funktionsdeklarationssyntax im “alten Stil” verwendet. Sie erklären implizit ein int Parameter aufgerufen vooid.

  • Dies scheint der Fall zu sein. Wenn Sie “vooid=42; return vooid;” hinzufügen an main erhalten Sie ebenfalls einen Rückgabewert von 42.

    – Jeff Ames

    13. Februar 2011 um 22:46 Uhr


  • Aargghh, du hast Recht. Wenn ich hinzufüge -std=c99Ich bekomme qq.c:1: warning: type of 'vooid' defaults to 'int'.

    – paxdiablo

    13. Februar 2011 um 22:48 Uhr

Benutzeravatar von Michael Goldshteyn
Michael Goldshteyn

Es ist gültiger Code, weil myprog.c enthält:

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

vooid enthält eins plus die Anzahl der übergebenen Argumente (d. h. argc). Sie haben also praktisch nur umbenannt argc zu vooid.

  • Wenn Sie “return vaoid;” stattdessen gibt es tatsächlich 1 + num. von Argumenten.

    – Jeff Ames

    13. Februar 2011 um 22:48 Uhr

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

    – Martin Beckett

    14. Februar 2011 um 2:21 Uhr

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

Es ist nur gcc -std=c89 -Wall -o qq qq.c und gcc -std=gnu89 -Wall -o qq qq.c keine Warnung ausgeben. Alle anderen Standards geben eine Warnung über den impliziten Typ aus int zum 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.

1423610cookie-check“int main (leer)”? Wie funktioniert das?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy