Was macht dieses Programm?
main(_){write(read(0,&_,1)&&main());}
Bevor wir es analysieren, machen wir es prettify:
main(_) {
write (read(0, &_, 1) && main());
}
Zunächst sollten Sie wissen, dass _
eine gültige Variablenname ist, wenn auch eine hässliche ein.Sagen wir es ändern:
main(argc) {
write(read(0, &argc, 1) && main());
}
Als nächstes erkennen, dass der Rückgabetyp einer Funktion und der Typ eines Parameters in C optional sind (aber nicht in C++):
int main(int argc) {
write(read(0, &argc, 1) && main());
}
Als nächstes verstehen, wie Rückgabewerte funktionieren. Bei bestimmten CPU-Typen wird der Rückgabewert immer in denselben Registern gespeichert (z. B. EAX auf x86). Wenn Sie also eine return
-Anweisung weglassen, ist der Rückgabewert wahrscheinlich, was auch immer die zuletzt zurückgegebene Funktion sein wird.
int main(int argc) {
int result = write(read(0, &argc, 1) && main());
return result;
}
Der Aufruf von read
ist mehr oder weniger deutlich: sie liest aus Standard-in (Dateideskriptor 0) ist, in den Speicher an &argc
befindet, für 1
Byte. Es gibt 1
zurück, wenn das Lesen erfolgreich war, und andernfalls 0.
&&
ist der logische "und" -Operator. Es bewertet seine rechte Seite genau dann, wenn es auf der linken Seite "wahr" ist (technisch ist jeder Wert ungleich null). Das Ergebnis des Ausdrucks &&
ist ein int
, der immer 1 (für "wahr") oder 0 (für falsch) ist. In diesem Fall ruft die rechte Seite main
ohne Argumente auf. Das Aufrufen von main
ohne Argumente nach der Deklaration mit 1 Argument ist ein nicht definiertes Verhalten. Trotzdem funktioniert es oft, solange Sie sich nicht um den Anfangswert des Parameters argc
kümmern. Das Ergebnis des &&
wird dann an write()
übergeben. So sieht unser Code jetzt wie folgt aus:
int main(int argc) {
int read_result = read(0, &argc, 1) && main();
int result = write(read_result);
return result;
}
Hmm. Ein kurzer Blick auf die man-Seiten zeigt, dass write
drei Argumente braucht, nicht eins. Ein weiterer Fall von undefiniertem Verhalten. Genauso wie wir main
mit zu wenigen Argumenten aufrufen, können wir nicht vorhersagen, was write
für sein zweites und drittes Argument erhalten wird. Auf typischen Computern bekommen sie etwas, aber wir können nicht sicher was. (Auf atypischen Computern können seltsame Dinge passieren.) Der Autor verlässt sich auf write
Empfangen, was zuvor auf dem Speicherstapel gespeichert wurde. Und er verlässt sich auf , die ist das zweite und dritte Argument zu lesen.
int main(int argc) {
int read_result = read(0, &argc, 1) && main();
int result = write(read_result, &argc, 1);
return result;
}
Befestigung der ungültigen Aufruf main
und Header hinzugefügt, und die Erweiterung des &&
haben wir:
#include <unistd.h>
int main(int argc, int argv) {
int result;
result = read(0, &argc, 1);
if(result) result = main(argc, argv);
result = write(result, &argc, 1);
return result;
}
Schlussfolgerungen
Dieses Programm wird nicht wie erwartet auf viele Computer. Selbst wenn Sie denselben Computer wie den ursprünglichen Autor verwenden, funktioniert es möglicherweise nicht auf einem anderen Betriebssystem. Selbst wenn Sie denselben Computer und dasselbe Betriebssystem verwenden, wird es bei vielen Compilern nicht funktionieren. Selbst wenn Sie denselben Computer-Compiler und dasselbe Betriebssystem verwenden, funktioniert es möglicherweise nicht, wenn Sie die Befehlszeilen-Flags des Compilers ändern.
Wie ich in den Kommentaren sagte, hat die Frage keine gültige Antwort.Wenn Sie einen Veranstalter oder einen Wettkampfrichter gefunden haben, der etwas anderes sagt, laden Sie ihn nicht zu Ihrem nächsten Wettbewerb ein.
Dieses Programm wird nicht in C++ kompilieren. Entfernen des C++ - Tags –
@ Robo Ah danke. Ich war sorglos. – RaunakS
Sogar in C ruft dieses Programm mehrfach undefiniertes Verhalten auf. Das Ergebnis ist nur für bestimmte Compiler vorhersagbar, die auf bestimmte Arten von CPUs abzielen (selbst bei Codegolf macht dieses Programm nur bei einer bestimmten Optimierungsebene etwas Interessantes). Richtige Antworten zu "Was macht dieses Programm?" schließe ein: "Es kommt darauf an", "Was immer es will" und "Es wird dich entlassen". –