Boolescher Wert in ifdef: Ist "#ifdef A && B" dasselbe wie "#if defined (A) && defined (B)"?

83

In C ++ ist dies:

#ifdef A && B

das Gleiche wie:

#if defined(A) && defined(B)

?

Ich dachte, es wäre nicht so, aber ich konnte keinen Unterschied zu meinem Compiler (VS2005) feststellen.

Criddell
quelle
1
Mögliches Duplikat von: stackoverflow.com/questions/965700/… Ich sehe, dass es sich um C und C ++ handelt, aber die Präprozessoren sind im Grunde die gleichen: stackoverflow.com/questions/5085533/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
Wird jemand den Standard zitieren und interpretieren, um zu entscheiden, ob er legal ist oder nicht (er sollte nicht sicher funktionieren, aber kompiliert werden)? Ich kann nach 15 Minuten Lesen von Kapitel "16 Vorverarbeitungsanweisungen" nicht mehr.
Ciro Santilli 法轮功 冠状 病 六四 事件 29

Antworten:

91

Sie sind nicht gleich. Der erste funktioniert nicht (ich habe in gcc 4.4.1 getestet). Fehlermeldung war:

test.cc:1:15: Warnung: Zusätzliche Token am Ende der Direktive #ifdef

Wenn Sie überprüfen möchten, ob mehrere Dinge definiert sind, verwenden Sie die zweite.

Evan Teran
quelle
Danke für das Kontrollieren. Ich verwende den Compiler von Microsoft und es scheint dies zuzulassen, aber es schien mir einfach nicht richtig zu sein.
Criddell
2
Sie können die Dinge nicht mit einem einzigen Compiler beweisen. Beziehen Sie sich auf den Standard, der besagt, dass dies ungültig ist.
Leichtigkeitsrennen im Orbit
@LightnessRacesinOrbit Einige Compiler erweitern jedoch den Standard. Die Aussage "es funktioniert in einem bestimmten Compiler" ist kein Versuch, seine Gültigkeit zu beweisen. Es ist zu beachten, dass ein bestimmter Compiler den Standard auf eine bestimmte Weise erweitert.
Fund Monica Klage
@QPaysTaxes: Einverstanden, aber diese Antwort macht das nicht. Es beantwortet eine Frage, die "in C ++ ..." mit einer allgemeinen Tatsache über C ++ beginnt. Auf den ersten Blick testete Evan seine Theorie mit einem Compiler und ging dann davon aus, dass sie für alle gilt, als Garantie für die Sprache selbst. Wenn er feststellte, dass dieses Verhalten eine GCC-Erweiterung ist und sagte "Dies ist eine GCC-Erweiterung" (mit Link zum Referenzmaterial), wäre das in Ordnung! (obwohl nicht wirklich eine Antwort auf diese spezielle Frage)
Leichtigkeitsrennen im Orbit
1
Obwohl es keine Reihe von positiven Tests könnte „beweisen“ , dass es ist gültig, ist eine einzige negative ausreichend zu beweisen , dass es nicht ist oder dass es zumindest zu verwenden , nicht ratsam. Obwohl es nett wäre, auf den Standard zu verweisen, ist der Nachweis, dass er in mindestens einem großen Compiler nicht funktioniert, ein ausreichender Beweis, um für die Zwecke dieser Diskussion zu sagen, dass er nicht funktioniert.
Zeel
48

Bedingte Kompilierung

Sie können den definierten Operator in der Direktive #if verwenden, um Ausdrücke zu verwenden, die innerhalb einer Präprozessorzeile 0 oder 1 ergeben. Dies erspart Ihnen die Verwendung verschachtelter Vorverarbeitungsanweisungen. Die Klammern um den Bezeichner sind optional. Zum Beispiel:

#if defined (MAX) && ! defined (MIN)  

Ohne den definierten Operator müssten Sie die folgenden zwei Anweisungen einschließen, um das obige Beispiel auszuführen:

#ifdef max 
#ifndef min
Svetlozar Angelov
quelle
2
Während das, was Sie sagen, richtig ist, beantwortet dies die Frage überhaupt nicht. Er fragte, ob die beiden gleich sind ... sie sind es nicht.
Evan Teran
1
Ich denke, es heißt "sie sind nicht gleich", man kann sehen, dass es erklärt, wie man ein Äquivalent von #if defined (COND_A) && defined (COND_B) macht, das sich von #ifdef COND_A && COND_B unterscheidet
Svetlozar Angelov
In jedem Fall ist dies ein nützlicher Hinweis.
Paul Masri-Stone
2

Die folgenden Ergebnisse sind gleich:

1.

#define A
#define B
#if(defined A && defined B)
printf("define test");
#endif

2.

#ifdef A
#ifdef B
printf("define test");
#endif
#endif
viel gut
quelle
1
Können Sie bitte einen Kommentar hinzufügen, um zu beschreiben, wie dies die Frage beantwortet, was aus Ihrer Antwort nicht klar hervorgeht.
James Wood
Diese Antwort ist zwar technisch korrekt, beantwortet die Frage jedoch nicht genau und impliziert eine falsche Verwendung. Während die beiden Blöcke dasselbe tun, ist das Verschachteln von zwei ifs nicht dasselbe wie das Verwenden von &&. Andere Bedingungen, wie z. B. eine #else, können ein Problem verursachen. Nur die erste Option bedeutet genau das, wonach der Fragesteller gefragt hat.
Zeel
1

Für diejenigen, die zum Beispiel (UNIX / g ++) suchen, das sich ein wenig vom OP unterscheidet, kann dies helfen:

`

#if(defined A && defined B && defined C)
    const string foo = "xyz";
#else
#if(defined A && defined B)
    const string foo = "xy";
#else
#if(defined A && defined C)
    const string foo = "xz";
#else
#ifdef A
    const string foo = "x";
#endif
#endif
#endif
#endif
MikeB
quelle
Warum nicht einfach #elif anstelle von #else #if und eine Milliarde # endifs am Ende verwenden ...?
Elliott
-3

Ab VS2015 funktioniert keines der oben genannten. Die richtige Anweisung lautet:

#if (MAX && !MIN)

Sehen Sie hier mehr

Fabri
quelle
2
Sie haben eine Verknüpfung zur C # -Dokumentation erstellt, nicht zu C ++.
Revolver_Ocelot