Was ist, wenn ich main als Referenz für die Funktion definiere?
%Vor%Was wird passieren? Ich habe in einem Online-Compiler mit dem Fehler "Segmentierungsfehler" getestet:
Und unter VC ++ 2013 wird es ein Programm erstellen, das zur Laufzeit abstürzt!
Ein Code, der die Daten des Funktionszeigers als Code aufruft, wird kompiliert, was beim Start sofort zum Absturz führt.
Ich möchte auch ein ISO C ++ Standard-Zitat dazu.
Das Konzept wird nützlich sein, wenn Sie einen von zwei Eintrittspunkten abhängig von einem Makro wie diesem definieren wollen:
%Vor%Das ist kein konformes C ++ Programm. C ++ erfordert das (Abschnitt 3.6.1)
Ein Programm soll eine globale Funktion namens
enthaltenmain
Ihr Programm enthält eine globale Nicht-a-Funktion namens main
, die einen Namenskonflikt mit der benötigten main
-Funktion einführt.
Eine Begründung dafür wäre, dass die gehostete Umgebung während des Programmstarts einen Funktionsaufruf an main
ausführen kann. Dies entspricht nicht der Quellzeichenfolge main(args)
, bei der es sich um einen Funktionsaufruf, eine Funktionszeiger-Dereferenzierung, die Verwendung von operator()
für ein Funktionsobjekt oder den Aufbau einer Instanz des Typs main
handeln könnte. Nein, main
muss eine Funktion sein.
Eine zusätzliche Sache, die zu beachten ist, ist, dass der C ++ Standard nie sagt, was der Typ von main
ist und verhindert, dass Sie ihn beobachten. So können Implementierungen die Signatur neu schreiben (und tun!), Indem Sie z. B. eine von int argc, char** argv, char** envp
hinzufügen, die Sie weggelassen haben. Natürlich könnte es das nicht für deine main1
und main2
wissen.
Dies ist nützlich, wenn Sie abhängig von einem Makro einen der beiden Eingangspunkte definieren möchten.
Nein, nicht wirklich. Sie sollten dies tun:
%Vor%Dies wird bald klar geworden schlecht gebildet, dank der Auflösung von CWG-Ausgabe 1886 , derzeit im Status "vorläufig bereit", der unter [basic.start.main] unter anderem Folgendes hinzufügt:
Ein Programm, das eine Variable
main
im globalen Gültigkeitsbereich deklariert deklariert den Namenmain
mit C-Sprachverknüpfung (in einem beliebigen Namespace) schlecht gebildet.
Was in der Praxis passiert, hängt stark von der Implementierung ab.
In Ihrem Fall implementiert Ihr Compiler diese Referenz anscheinend als "verdeckter Zeiger". Zusätzlich dazu hat der Zeiger eine externe Verknüpfung. I.e. Ihr Programm exportiert ein externes Symbol namens main
, das tatsächlich mit dem Speicherort im Datensegment verknüpft ist, das von einem Zeiger belegt wird. Der Linker zeichnet, ohne zu viel hineinzuschauen, den Speicherort als Eingangspunkt des Programms auf.
Wenn Sie später versuchen, diesen Ort als Einstiegspunkt zu verwenden, wird der Segmentierungsfehler verursacht. Erstens gibt es an diesem Ort keinen sinnvollen Code. Zweitens kann ein bloßer Versuch, die Kontrolle an einen Ort innerhalb eines Datensegments zu übergeben, die Mechanismen zum Schutz der Datenausführung Ihrer Plattform auslösen.
Sie haben damit anscheinend gehofft, dass der Verweis optimiert wird, d. h. dass main
nur ein anderer Name für main1
wird. In deinem Fall ist es nicht passiert. Die Referenz überlebte als unabhängiges externes Objekt.
Sieht so aus, als hätten Sie bereits die Frage beantwortet, was passiert.
Soweit wie, in Ihrem Code main
ist ein Verweis / Zeiger auf eine Funktion. Das ist anders als eine Funktion. Und ich würde einen Segmentfehler erwarten, wenn der Code einen Zeiger anstelle einer Funktion aufruft.
Tags und Links c++ reference language-lawyer main iso