int main;
-
int main;ist doch keine Funktion.
-
idontgotit schrieb:
int main;ist doch keine Funktion.main muss eine Funktion sein, damit es ein gültiges, portables Programm ist. Da steht aber nicht, dass es keine anderen Formen von main geben darf.
-
Aber da steht doch, dass jedes C++ Programm eine main-Funktion haben soll. Die Quelldatei
X.cpp
int main;enthält aber keine Funktion main, deshalb darf das doch gar nicht kompilieren..
-
SeppJ schrieb:
main muss eine Funktion sein, damit es ein gültiges, portables Programm ist. Da steht aber nicht, dass es keine anderen Formen von main geben darf.

Es steht, dass main eine Funktion ist, die
intzurückgibt. Den einzigen Freiraum, den der Standard lässt, sind die Parameter.int main;ist eine Variable (d.h. keine Funktion) und folglich gibt es auch keinen int zurück.Da der Name mit einer standardkonformen Funktion int main() kollidiert, hat das Programm keine Funktion main(). Da es diese aber haben muss, ist es verboten, keine zu haben, ist es verboten eine Variable ::main zu definieren.
-
Incocnito schrieb:
Aber da steht doch, dass jedes C++ Programm eine main-Funktion haben soll. Die Quelldatei
X.cpp
int main;enthält aber keine Funktion main, deshalb darf das doch gar nicht kompilieren..
Hast du noch nie ein Programm mit mehreren Modulen compiliert? Die enthalten in der Regel alle kein main.
idontgotit schrieb:
SeppJ schrieb:
main muss eine Funktion sein, damit es ein gültiges, portables Programm ist. Da steht aber nicht, dass es keine anderen Formen von main geben darf.

Es steht, dass main eine Funktion ist, die
intzurückgibt. Den einzigen Freiraum, den der Standard lässt, sind die Parameter.int main;ist eine Variable (d.h. keine Funktion) und folglich gibt es auch keinen int zurück.Da der Name mit einer standardkonformen Funktion int main() kollidiert, hat das Programm keine Funktion main(). Da es diese aber haben muss, ist es verboten, keine zu haben, ist es verboten eine Variable ::main zu definieren.
Nö, heißt es nicht. Es heißt nur, dass du, wenn du eine main Funktion mit den genannten Parametern hast, dann kann man daraus ein gültiges Programm erstellen. Du darfst andere mains definieren wie du lustig bist. Leute, könnt ihr alle nicht mehr zwischen Compiler und Linker unterscheiden?

-
SeppJ schrieb:
Du darfst andere mains definieren wie du lustig bist. Leute, könnt ihr alle nicht mehr zwischen Compiler und Linker unterscheiden?

Sorry ich schreib mein Compiler in Java

-
SeppJ schrieb:
Leute, könnt ihr alle nicht mehr zwischen Compiler und Linker unterscheiden?

Wenn ich Programm schreibe, dann meine ich das, was der C++-Standard darunter versteht (keine Ahnung, wie du plötzlich auf Compiler kommst):
C++ Standard schrieb:
A program consists of one or more translation units (Clause 2) linked together.
Wenn im Ursprungspost von "das Programm startet und stürzt ab" die Rede ist, dann ist das wohl die einzig sinnvolle Interpretation.
Mods, könnt ihr alle nicht mehr zwischen Programm und Übersetzungseinheit unterscheiden?
C++ Standard schrieb:
If there is more than one [..] matching entity, the program is ill-formed.
Wenn jemand eine globale Variable
int main;definiert, dann ist das Programm(!) ill-formed, da es entweder (a) mehrere Symbole "main" enthält oder (b) keine Funktion "main" besitzt.Was du vorher schriebst, dürfte damit widerlegt sein.
SeppJ schrieb:
Es heißt nur, dass du, wenn du eine main Funktion mit den genannten Parametern hast, dann kann man daraus ein gültiges Programm erstellen. Du darfst andere mains definieren wie du lustig bist.
-
@idontgotit
Du schießt fast immer daneben, aber mit ill-formed hast ein bisschen getroffen.// a non-ill-formed program int main; int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) {....}Deswegen sind die Satze bezüglich den Namen main eigentlich auch nur Empfehlungen/Ratschläge/Verpflichtungen, aber keine harte Einschräkung/Gesetzt/Regeln. Daraus folgt, dass ein Compiler auch nicht harte Fehler melden muss.
-
idontgotit schrieb:
SeppJ schrieb:
Leute, könnt ihr alle nicht mehr zwischen Compiler und Linker unterscheiden?

Wenn ich Programm schreibe, dann meine ich das, was der C++-Standard darunter versteht (keine Ahnung, wie du plötzlich auf Compiler kommst):
Weil das das Problem ist! Du darfst mains definieren wie du lustig bist. Bloß wenn du anfängst, die falschen mains zu einem Programm zusammenzulinken, dann ist dir nicht mehr garantiert, dass ein lauffähiges Programm rauskommt. Es darf aber selbstverständlich ein lauffähiges Programm rauskommen, das Definieren anderer mains ist nicht verboten und es ist mir immer noch nicht klar, wo du dieses Verbot siehst. Der Standard erwähnt sogar explizit, dass andere Arten ein gültiges Programm zu erhalten erlaubt sind (im Teil über Startup and Termination und über hosted und freestanding evironments [aus dem Gedächtnis zitiert]).
-
SeppJ schrieb:
Es darf aber selbstverständlich ein lauffähiges Programm rauskommen, das Definieren anderer mains ist nicht verboten und es ist mir immer noch nicht klar, wo du dieses Verbot siehst.
Das Definieren an sich ist nicht an sich verboten, nur kann man damit später nie ein gültiges Programm erstellen. Das habe ich so deutlich geschrieben.
SeppJ schrieb:
Der Standard erwähnt sogar explizit, dass andere Arten ein gültiges Programm zu erhalten erlaubt sind (im Teil über Startup and Termination und über hosted und freestanding evironments [aus dem Gedächtnis zitiert]).
Es steht nur, dass die freestanding environments auf main verzichten dürfen, ist es hosted (wovon wohl die Rede ist), ist eine globale Funktion main, die als Einstiegspunkt genutzt wird, Pflicht.
Zeus schrieb:
// a non-ill-formed program int main; int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) {....}Was soll daran legal sein? Nur weil es der (sowieso nicht standardgetreue) MSVC akzeptiert, heisst das noch lange nicht, dass es nicht ill-formed wäre.
-
idontgotit schrieb:
Zeus schrieb:
// a non-ill-formed program int main; int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) {....}Was soll daran legal sein? Nur weil es der (sowieso nicht standardgetreue) MSVC akzeptiert, heisst das noch lange nicht, dass es nicht ill-formed wäre.
Willst du nur trollen, soll ich jetzt deine eigene Kommentare zitieren, warum das Programm nicht ill-formed ist?
If there is more than one [..] matching entity, the program is ill-formed.
Ein Win32-API-Programm hat keine Main Funktion als Einstiegspunkt. Daher gibst auch durch die Deklaration von int main auch nur eine Entity.
-
Zeus schrieb:
Willst du nur trollen
Nichts liegt mir ferner.
Zeus schrieb:
Ein Win32-API-Programm hat keine Main Funktion als Einstiegspunkt.
Die muss es aber haben, sonst ist es kein C++.
C++ Standard schrieb:
A program shall contain a global function called main, which is the designated start of the program. It is implementation-defined whether a program in a freestanding environment is required to define a main function.
Für dein Beispiel wichtig: "designated start of the program"
Für SeppJ wichtig: "It is implementation-defined [...] in a freestanding environment".
-
Ist dir der Unterschied nicht klar, zwischen müssen und dürfen? Ja, ein Programm ohne int main() oder int main(int char**) muss nicht funktionieren. Es darf aber funktionieren, wenn es andere mains gibt! Möchtest du denn verbieten, dass ich in meinem freestanding environment eine globale Variable namens main definiere? Das muss der Compiler fressen. Bloß wenn ich hinterher versuche, diese Variable wie eine main-Funktion zu linken, dann darf ich nicht erwarten (außer ich habe ganz schlaue Tricks angestellt), dass ein gültiges Programm rauskommt. Tut es ja auch nicht! Darum darf ich trotzdem eine Variable haben, die so heißt. Was ist daran so schwer zu kapieren?
Da ich das inzwischen dreimal geschrieben habe und als Antwort immer Stellen aus dem Standard vorgesetzt bekommen haben, die mich bestätigen, sehe ich keine Grund noch ein viertes Mal diese Antwort zu geben, wenn nichts neues kommt.
-
SeppJ schrieb:
Da ich das inzwischen dreimal geschrieben habe und als Antwort immer Stellen aus dem Standard vorgesetzt bekommen haben, die mich bestätigen, sehe ich keine Grund noch ein viertes Mal diese Antwort zu geben, wenn nichts neues kommt.
Gut, sehe es so, dass ich es nicht schaffe, den Standard richtig zu interpretieren und du mir zeigst, wie es geht. Kapiert habe ich ihn immer noch nicht.
Möchtest du denn verbieten, dass ich in meinem freestanding environment eine globale Variable namens main definiere?
Bitte lass das freestanding environment weg, da ist
allesvieles erlaubt und es kommt selten vor. (Btw: Wenn eine Win32-Anwendung als freestanding gilt, hat Zeus natürlich recht)In meinen Augen steht
Ja, ein Programm ohne int main() oder int main(int char**) muss nicht funktionieren
(in hosted environments) in direkten Gegensatz zu
A program shall contain a global function called main, which is the designated start of the program.
da jedes (gehostete) Programm eine Funktion haben muss (== "shall" und "shall" != "darf"), die "main" heisst und "int" zurückgibt.
Was meinst du damit:
Es darf aber funktionieren, wenn es andere mains gibt!
Gloable Funktionen, die "main" heissen und "int" zurückgeben oder etwas anderes?
Letzteres ist in meinem Verständnis unmöglich, da ein (gehostetes) Programm ein "int main(irgendwas)" haben muss (was als Einstiegspunkt genutzt wird).Bloß wenn ich hinterher versuche, diese Variable wie eine main-Funktion zu linken, dann darf ich nicht erwarten (außer ich habe ganz schlaue Tricks angestellt), dass ein gültiges Programm rauskommt.
Sind diese schlauen Tricks mit dem Standard verträglich?
-
idontgotit schrieb:
Was meinst du damit:
Es darf aber funktionieren, wenn es andere mains gibt!
Gloable Funktionen, die "main" heissen und "int" zurückgeben oder etwas anderes?
Letzteres ist in meinem Verständnis unmöglich, da ein (gehostetes) Programm ein "int main(irgendwas)" haben muss (was als Einstiegspunkt genutzt wird).Das Programm des Threaderstellers funktioniert ja auch nicht! Denn es hat keine gültige main-Funktion! Aber der Compiler muss ein
int main;schlucken, denn er kann ja nicht wissen, was ich später damit anstelle. Vielleicht will ich ja kein lauffähiges Programm. Vielleicht will ich das später als Variable in einer freestanding-Implementierung benutzen. Vielleicht will ich das hinterher mit einem wilden Fortran-Code linken, indem die Startfunktion ganz anders heißt. Vielleicht will ich einen Editor für Objektdateien testen. Wenn ichint main;schreibe, dann soll mir einfach nur eine Objektdatei erstellt werden, in der ein Symbol namensmainexistiert, das Speicherplatz für einen Integer ist. Was ich mit dem Symbol später anstelle, das hat den Compiler erst einmal gar nichts anzugehen. main ist für den Compiler nichts besonderes*, interessant wird es erst, wenn ein fertiges Programm erstellt wird. Dann sollte die main eine Funktion mit passender Signatur sein.Bloß wenn ich hinterher versuche, diese Variable wie eine main-Funktion zu linken, dann darf ich nicht erwarten (außer ich habe ganz schlaue Tricks angestellt), dass ein gültiges Programm rauskommt.
Sind diese schlauen Tricks mit dem Standard verträglich?
Bestimmt nicht. Ich weiß nicht mal, ob so etwas möglich ist, Jedenfalls ist es vorstellbar.
*: Außer der Sonderregelung, dass in einer Funktion namens main ein return 0 implizit ist.
-
Danke SeppJ.
-
wow einer der sich bedankt. welch seltenheit in diesem forum.

-
Also zusammengefasst:
a) int main; sollte vom Compiler geschluckt werden, weil es direkt beim Übersetzen erstmal keiner Regel widerspricht.
b) Beim Linken eines konformen C++-Programms auf einem "hosted environment" muss es dann zu einem Fehler kommen, weil der Standard verlangt, dass erstens eine Funktion int main(/*params*/) in irgendeiner ÜE vorhanden sein muss und zweitens das Symbol dieser Funktion mit dem Symbol der Variablen aus der anderen ÜE kollidiert.- Wenn der Linker sich nicht beschwert, weil er entweder eine andere Funktion als Einstiegspunkt akzeptiert (z.B. _tWinMain) oder aber durch irgendwelche obskure magie aus int main; eine Funktion erkennt (wie beim TE offenbar der Fall), dann ist das eine Erweiterung des jeweiligen Linkers, die nicht mehr Standardkonform ist.
- Zeus' Code ist damit nicht ill-formed, das resultieren Programm dagegen schon. Dass es funktioniert, liegt an der Erweiterung des MSVC.
- Ebenso ist das Programm des Threaderstellers im Sinne des Standars ill-formed. Dass der Linker keine Zähne spuckt, liegt vermutlich an einer entsprechenden Erweiterung. Dass das Programm dann abstürzt liegt daran, dass die Erweiterung nicht gemäß ihren Spezifikationen genutzt wurde (wie auch immer die aussehen mögen)
- Wenn ich die ÜEs nicht von einem C++-Linker verwursten lasse (SeppJ's hypotetisches Fortran-Beispiel), zieht Punkt b) eh nicht und es darf alles geschehen.Richtig?
-
Auch beim MSVC ist main() der Einstiegspunkt, nur daß diese Funktion eben schon in den Runtime-Libs implementiert ist (und diese wird dazugelinkt sobald man entsprechende Optionen (/SUBSYSTEM) beim Linker einstellt):
int main(/*Parameter*/) { // code return WinMain(/*Parameter*/); }Und nur aus User-Sicht ist also WinMain() der Einstiegspunkt.
-
Wo soll es denn ein Problem geben?
Wenn es mit Namen von Variablen Konflikte mit dem Compiler oder Linker gibt, wählt man einfach andere! 