"cout" vor Main Funktion
-
Guten Tag,
ich habe in einem anderen Forum zufällig einen Quelltext gefunden, der fehlerhaft war. Der Fehler liegt darin, dass er cout außerhalb der Main Funktion verwendet hat.
also z.B.
#include <iostream> using namespace std; #define test #ifdef test cout << "dies ist ein tes"; //oder std::cout #else #define test #endif int main(void) { }Das klappt nicht, bei mir fliegt die C2143(fehlendes ; vor <<) und die C4430 - fehlender Typespezifierer - int wird angenommen. hinweis: "Default-int" wird von c++ nicht unterstützt.
wieso es nicht geht ist mir klar, aber ich würde gerne den Grund wissen. Der TE hat dafür vom Antwortersteller auch keine sinnvolle Antwort bekommen und gibt es eine Möglichkeit seinen "Wunsch" auch zu realisieren ohne das die ifndef Sachen in die Main Funktion zu schreiben?
Danke
-
Weil in C++ die Ausführung des Programms nicht von oben nach unten erfolgt, sondern in der Funktion main startet.
Aber hey, du hast Glück, es geht nämlich:
#include <iostream> #define TEST #ifdef TEST int __test_main__(); int main() { std::cout << "dies ist ein test;"; // und was du so willst return __test_main__(); } # define main __test_main__ #endif int main(void) { std::cout << "hallo welt aus main\n"; }
-
Servus,
erstmal danke für Deine Hilfe,
aber:
"Fehler 1 error C4716: '__test_main__': Muss einen Wert zurückgeben c:\users\alex\documents\visual studio 2010\projects\isndef\isndef\main.cpp 58"
Leider wird Dein Quelltext bei mir nicht kompiliert
-
Hab das "
return 0;" am Ende von main vergessen. So einen Schwachsinn teste ich doch nicht.
-
Also erstmal geht immer noch nicht.
Aber irgendwie versteh cih Deine Erklärung auch nicht so ganz.
Du sagst mir dass in der Funktion Main gestartet wird. Schön und gut, aber wieso wird dann "mein" (bzw der den ich gesehen habe) Quelltext nicht übersetzt?
-
#include <iostream> #define TEST #ifdef TEST int __test_main__(); int main() { std::cout << "dies ist ein test\n"; // und was du so willst return __test_main__(); } # define main __test_main__ #endif int main(void) { std::cout << "hallo welt aus main\n"; return 0; }
-
Was man tun könnte (aber nicht sollte, wenn man es vermeiden kann) ist etwas wie
#include <iostream> #ifdef TEST std::ostream &DO_NOT_DO_THIS_EVER = std::cout << "test" << std::endl; #endif int main() { // Programm hier }In dem Fall wird eine globale Variable mit dem Rückgabewert des Ausdrucks initialisiert, und es ist garantiert, dass das vor dem Eintritt in main passiert. Dementsprechend wird der Ausdruck vor dem Eintritt in main ausgewertet.
Der ursprüngliche Code funktioniert schlicht deshalb nicht, weil die Anweisung nirgendwo im Kontrollfluss der Anwendung steht. Die Sprache sieht solche Kinkerlitzchen stumpf nicht vor.
Übrigens ist der obrige Trick ausgesprochen dreckig und nicht zu empfehlen. Was soll das Ganze überhaupt?
-
Die "Idee" des anderen Posts ist mir ja klar. Er will prüfen, ob das ganze Definiert ist und dann eine Meldung ausgeben "X ist definiert".
Ist der Grund nun einfach, dass er bei "Main" anfängt? Wieso ist das ein Problem? Selbst ein Cout, welches er nie erreicht, wäre ja erstmal kein Problem (zumidnestens nicht aus technischer Sicht), dann würde es halt nicht ausgegeben werden. Aber der Compiler übersetzt es ja noch nichtmal...
Mir sind auch beide "Alternativen Lösungsvorschläge" nicht so ganz klar.
Bei der Lösng von Zinken, wonach entscheidet er welche "Main Funktion" zurückgeeben wird.
Dann ist mir noch nicht klar, was in Zeile 10 passiert.. Es müsste dort also dann die "Main" Funktion mit "hallo aus main" ausführen, aber wieso? __test_main__(); ist doch hier doch garnicht definiert.# define main __test_main__, wo er main in __test_main__ umbenennt kommt ja erst danach.
Sorry für die vielen Fragen. Wichtig ist mir v.a. nochmal eine genaue Erklärung, wieso der erste Post nicht kompiliert wird. Die Erklärung "Weil er halt zuerst nach der Main sucht" reicht bei meinem Wissensstand (leider) nicht aus, sorry

-
__test_main__(); wurde ja vorwärtsdeklariert siehe Zeile 6.
Durch das define in Zeile 12 wird Zeile 15 umbenannt.
Zeile 10 ruft also eifnach nur die aus Zeile 6 bekannte Funktion __test_main__(); auf, welche nach dem define aus Zeile 12 nun ab Zeile 15 implementiert ist.Das ganze normal geschrieben sieht dann so aus:
#include <iostream> int __test_main__(); int main() { std::cout << "dies ist ein test\n"; // und was du so willst return __test_main__(); } int __test_main_(void) { std::cout << "hallo welt aus main\n"; return 0; }Das ganze kann natürlich auch weiter vereinfacht werden...
-
Ok danke. Also ich versuchs nunmal so zu beschreiben wie ich es jetzt verstehe:
1.) Durch Zeile 6: int __test_main__(); weiß er, dass es eine Funktion __test_main__() gibt.
2.) In Zeile 10 führt er sie aus
3.) Durch Zeile 12 weiß er dass die Main funktion imt cout << "hallo aus der main" die __test_main__() istrichtig?
Wobei für mich immer noch die Frage ist, wieso der erste Post nicht kompiliert wird. Die Erklärung "Weil er halt zuerst nach der Main sucht" reicht bei meinem Wissensstand (leider) nicht aus. Wie gesagt in meiner Welt hat das doch erstmal nicht damit zu tun, wieso er da so rummeckert.
Anders gefragt: Ist das Problem, dass das "Cout" einfach so im Raum steht und in keiner Funktion steht? "Muss" ein Cout immer in einer Funktion stehen. Wenn nein was darf außerhalb einer Funktion stehen?
#define, #ifndef, #ifdef, #include, globale Variablen, sonst nix?Danke
-
Suchst du vielleicht eigentlich nach
#ifdef TEST # error "TEST schon definiert." #else # define TEST #endif?
-
Zenker schrieb:
Anders gefragt: Ist das Problem, dass das "Cout" einfach so im Raum steht und in keiner Funktion steht? "Muss" ein Cout immer in einer Funktion stehen. Wenn nein was darf außerhalb einer Funktion stehen?
#define, #ifndef, #ifdef, #include, globale Variablen, sonst nix?
DankeSchau mal hier: Hyperlinked C++ BNF Grammar
Allerdings würd ich mir an Deiner Stelle nicht so den Kopf darüber zerbrechen, was Zinkens code genau macht (da wie schon erwähnt eher n mieser Trick).
-
Sowas wäre eine Lösung, aber Dein Quelltext wird bei mir nicht übersetzt (C1189)
-
Was willst du eigentlich genau machen? Sei präzise, denn bislang sah ich hier nur Sachen, die man nie im Leben so verwenden wird.
-
Danke, hab mir gerade mal BNF überflogen und mir den Wiki Artikel dazu durchgelesen... Hab aber noch nicht so ganz kapiert was die BNF ist, ist sie die "Grammatik der Compiler?"
Werd den kompletten Artikel wohl morgen mal nach dem Aufstehen durchlesen.
Dank euch allen schonmal
-
Also ok, ich veruschs nohchmal zu anders zu formulieren:
Ich habe in einem anderen Forum einen Quelltext gefunden, der in etwa so aussieht:
#include <iostream> using namespace std; #define test #ifdef test cout << "dies ist ein tes"; //oder std::cout #else #define test #endif int main(void) { }Die Idee des Authors ist wohl, zu prüfen ob test schon definiert ist und wenn ja eine Meldung darüber auszugeben (wohl zu testzwecken).
Dieser Code wird von meinem Compiler nicht übersetzt und ich frage mich wieso. Kommentiere ich die Cout Zeile nach #ifdef aus, wirds ja übersetzt. Eine funktionierende Version ist für mich zweitrangig. Ich frage mich nur wieso dieser Quelltext eigentlich nicht übersetzt wird. Mir, als Mensch, ist die Idee des Authors des Quelltextes ja klar.
-
Das wäre auch eine Möglichkeit, aber das alles finde ich mehr oder minder quatsch. MSVC highlighted dir sogar den definierten Bereich.
#include <iostream> #define test #ifdef test #define testdefine "test ist definiert" #else #define testdefine "test nicht definiert" #endif int main() { std::cout << testdefine; }
-
Ok, die Lösung sieht für mich schonmal sehr gut aus und wird das machen, was ich erwarte.
Danke.
Aber cout DIREKT im #define Teil ist VERBOTEN / nicht erlaubt, richtig?
Wie gesagt wichtiger als eine funktionierende Lösung ist für mich der Grund, wieso der Ursprungsteil nicht kompiliert wird.
-
Zenker schrieb:
Dieser Code wird von meinem Compiler nicht übersetzt und ich frage mich wieso. Kommentiere ich die Cout Zeile nach #ifdef aus, wirds ja übersetzt. Eine funktionierende Version ist für mich zweitrangig. Ich frage mich nur wieso dieser Quelltext eigentlich nicht übersetzt wird. Mir, als Mensch, ist die Idee des Authors des Quelltextes ja klar.
C++ erlaubt allgemain keine Anweisungen außerhalb von Funktionen. Wenn wir mal den Präprzessor weglassen, sieht das Programm so aus:
#include <iostream> std::cout << "Test"; int main() { }Und sowas ist in C++ nicht möglich, egal ob die Anweisung
cout << ...;,Sleep(5000);oder sonstwie lautet.Wann sollen solche Anweisungen auch ausgeführt werden? Am Start des Programms? Was ist, wenn über verschiedenste Dateien solche Anweisungen verteilt sind, in welcher Reihenfolge werden die dann ausgeführt? Von Übersichtlichkeit will ich mal gar nicht reden, auf jeden Fall gibt es einen Grund für die Funktion
main.Natürlich gibt es wie immer Ausnahmen: die Konstruktoren globaler oder statischer Variablen werden vor
mainin einer unspezifizierten Reihenfolge ausgeführt. Man kann also Code vormainausführen. Für solche Fälle sollte man das aber nicht benutzen.Übrigens gibt es auch die Möglichkeit, über Präprozessordirektiven dir beim Kompilieren Meldungen im Kompilierlogfenster des Compilers ausgeben zu lassen, das wäre in dem Fall wahrscheinlich angebrachter (die genauen Direktiven müsste ich jetzt aber erst nachsehen (war glaube ich sowas wie
#pragma message), kommt sicher auch auf den Compiler an).
-
Naja man könnte ja sich denken, dass er die ganzen Präprozessorbefehle die vor der Main stehen Zeile durchgeht. Das cout gehört ja zu #ifdef und steht ja nicht im leeren Raum.
Der Fehler würde dann ja zur Compilezeit auftreten (hatte ich nicht bedacht) und damit gäbs ja garkein Terminal, auf was cout ausgeben könnte. Ich denke mir ist nun alles klar.Danke
-
Der Präprozessor ist unabhängig vom Compiler. Der Compiler bekommt von den Präprozessordirektiven (z.B.
#ifdef) nichts mit, die hat der Präprozessor entfernt. Für den Compiler steht dascoutalso schon im "leeren Raum".Das mit dem Terminal ist auch irrelevant, folgendes Programm kompiliert ebenso nicht:
void do_nothing() {} do_nothing(); // <-- Fehler int main() {}Anweisungen außerhalb von Funktionen sind in C++ ganz einfach nicht erlaubt.