To działa w oparciu o wiele dziwactw, które C pozwala ci zrobić, a niektóre niezdefiniowane zachowania działają na twoją korzyść. W kolejności:
main(a) { ...
Rodzaje Zakłada się int
czy nieokreślony, więc jest to równoznaczne z:
int main(int a) { ...
Nawet main
ma przyjąć wartość 0 lub 2 argumenty, a to jest niezdefiniowane zachowanie , może to być dozwolone jako ignorowanie brakującego drugiego argumentu.
Następnie ciało, które wyrzucę. Zauważ, że a
jest int
zgodnie main
:
printf(a,
34,
a = "main(a){printf(a,34,a=%c%s%c,34);}",
34);
Kolejność oceny argumentów jest niezdefiniowana, ale jesteśmy powołując się na 3. argumentu - Przypisanie - Pierwsze oceniana jako pierwszy. Opieramy się również na niezdefiniowanym zachowaniu możliwości przypisania char *
do int
. Należy również zauważyć, że 34 to wartość ASCII wynosząca "
. Zatem zamierzone oddziaływanie programu jest:
int main(int a, char**) {
printf("main(a){printf(a,34,a=%c%s%c,34);}",
'"',
"main(a){printf(a,34,a=%c%s%c,34);}",
'"');
return 0; // also left off
}
, które po ocenie, produkuje:
main(a){printf(a,34,a="main(a){printf(a,34,a=%c%s%c,34);}",34);}
który był oryginalny program. Tada!
3 ostrzeżenia i bez błędu oznacza udaną kompilację dlaczego go nie uruchamiasz? – Cestarian
@Cestarian Pytanie nie jest * czym * to robi - jest * jak * to robi? Stąd też tytuł. – Barry
To nie jest tak naprawdę najkrótszy program. Rzeczywisty najkrótszy ma długość 0 bajtów. Możesz skompilować skompilowany plik 0-bajtowy c do pliku wykonywalnego. Uruchomienie tego exe powoduje wydrukowanie 0 bajtów, co stanowi cały kod źródłowy oryginalnego programu. –