Problem mit #if #elif und #else
-
Moin zusammen,
ich komme bei folgendem Code nicht weiter:#include <conio.h> #include <iomanip> #include <cstdlib> #include <string> using namespace std; int i=5; #if(i==4) #define E "IF" #elif(i==5) #define E "ELIF" #else #define E "ELSE" #endif int main() { cout<<i<<endl<<E<<endl; return 0; }Meiner Meinung nach müsste nun "5" und dann "ELIF" ausgegeben werden. Stattdessen werden "5" und "ELSE" ausgegeben. Ich kann mir nicht erklären, warum nicht "ELIF" ausgegeben wird und würde gerne wissen, wo der Fehler liegt.
Vielen Dank schonmal im Voraus
Patrick
-
Die Präprozessorinstruktionen
#ifetc. arbeiten mit Makros, nicht mit Variablen.iist kein Makro, daher kann auchiweder 4 noch 5 sein.
Wieso arbeitest du nicht mitif?Kleines Beispiel für korrektes
#if:#define LibVersion 5 #if (LibVersion > 3) Lib::NewThing(); #endif
-
Weil das Präprozessor-Befehle sind und kein C++. Der Präprozessor ersetzt das alles, bevor der Compiler dran kommt. Und zu dem Zeitpunkt gibt es noch keine Variablen.
Nach dem Präprozessor sieht das dann so aus:
//... die ganzen includes lass ich mal weg using namespace std; int i=5; int main() { cout<<i<<endl<<"ELSE"<<endl; return 0; }
-
Der Fehler ist dass du den Präprozessor benutzt. Der Präprozessor kann nur Textersetzung und kein C++. Das i in Zeile 9 hat nichts mit dem i in Zeile 7 zu tun. Das i in Zeile 9 ist nicht definiert und deshalb wird i==4 als falsch bewertet. Gleiches gilt für i==5. Dann geht er in den #else-Zweig.
Wenn du normales if und else benutzt verschwinden diese Probleme. Alternativ definiere dein i als #define i 5, dann klappt auch das #if #else.
-
Du solltest dir mal anschauen, wie das Kompilieren von C/C++ Code so abläuft.
Vor der eigentlichen Kompilation rennt zunächst der sogenannte Präprozessor über deinen Code und verarbeitet "Präprozessordirektiven".Zu diesen Direktiven zählen z.B. #if und Konsorten, sowie das allgegenwärtige #include. Diese Direktiven werden vom Präprozessor verarbeitet, welcher wiederum einfache Textersetzung durchführt. Das heißt, ein #include wird z.B. einfach durch den Inhalt des Headers ersetzt. ein #if, dessen Bedingung nicht erfüllt ist, wird rausgefiltert und #define's werden einfach durch ihren Wert ersetzt.
Das wichtigste: Der Präprozessor SPRICHT WEDER C NOCH C++! Er hat keine Ahnung, was dein "int i = 5;" macht. Es ist einfach da und er überliest es.
Folglich kennt der Präprozessor kein i, welches er mit 4 oder 5 vergleichen könnte und wählt daher den #else Pfad.
-
Alles klar, vielen Dank für die schnellen Antworten und entschuldigt die rückblickend etwas dumme Frage^^.
Gibt es eine Möglichkeit, das zu verlesende Makro durch Eingabe zu belegen, also bspw. durch cin?
-
pattata schrieb:
Gibt es eine Möglichkeit, das zu verlesende Makro durch Eingabe zu belegen, also bspw. durch cin?
Das kann per Definition nicht gehen. Der Präprozessor läuft vor dem Kompilieren. Die Nutzereingabe läuft nach dem Kompilieren. Ohne Zeitmaschine wird das nichts.