Schreiben Sie niemals solchen Code.
Für j<1000
, j/1000
null (Integer - Division). So:
(&main + (&exit - &main)*(j/1000))(j+1);
ist äquivalent zu:
(&main + (&exit - &main)*0)(j+1);
Welches ist:
(&main)(j+1);
Welches ruft main
mit j+1
.
Wenn j == 1000
, dann kommen die gleichen Zeilen heraus wie:
(&main + (&exit - &main)*1)(j+1);
Was darauf hinausläuft
(&exit)(j+1);
Welches ist exit(j+1)
und verlässt das Programm.
(&exit)(j+1)
und exit(j+1)
sind im Wesentlichen dasselbe - zitiert C99 §6.3.2.1 / 4:
Ein Funktionsbezeichner ist ein Ausdruck mit dem Funktionstyp. Außer wenn es sich um den Operanden des Operators sizeof oder des Operators unary & handelt , wird ein Funktionsbezeichner vom Typ " Funktionsrückgabetyp " in einen Ausdruck mit dem Typ " konvertiert". Zeiger auf den Funktionsrückgabetyp .
exit
ist ein Funktionsbezeichner. Auch ohne das Unäre&
Adresse des Operators wird sie als Zeiger auf die Funktion behandelt. (Das &
macht es nur explizit.)
Funktionsaufrufe sind in §6.5.2.2 / 1 und folgenden beschrieben:
Der Ausdruck, der die aufgerufene Funktion bezeichnet, muss einen Typzeiger auf die Funktion haben die void zurückgibt oder einen anderen Objekttyp als einen Array-Typ zurückgibt.
So exit(j+1)
aufgrund der automatischen Konvertierung des Funktionstyps in einen Zeiger-zu-Funktionstyp und (&exit)(j+1)
funktioniert auch mit einer expliziten Konvertierung in einen Zeiger-zu-Funktionstyp.
Abgesehen davon ist der obige Code nicht konform ( main
nimmt entweder zwei oder gar keine Argumente an) und &exit - &main
ist meines Erachtens gemäß §6.5.6 / 9 undefiniert:
Wenn zwei Zeiger subtrahiert werden, zeigen beide auf Elemente desselben Array-Objekts oder einen nach dem letzten Element des Array-Objekts. ...
Die Addition (&main + ...)
wäre an sich gültig und könnte verwendet werden, wenn die hinzugefügte Menge Null wäre, da in §6.5.6 / 7 Folgendes steht:
Für die Zwecke dieser Operatoren verhält sich ein Zeiger auf ein Objekt, das kein Element eines Arrays ist, genauso wie ein Zeiger auf das erste Element eines Arrays der Länge eins mit dem Objekttyp als Elementtyp.
Das Hinzufügen von Null zu &main
wäre also in Ordnung (aber nicht sehr nützlich).
main
C ++ nicht aufrufen .