Ist #if defined MACRO äquivalent zu #ifdef MACRO?

Lesezeit: 5 Minuten

Benutzer-Avatar
msc

Ich habe Code, den ich zwei Modi haben möchte, debug und verbose. Ich definiere sie in meiner Header-Datei als

#define verbose TRUE
#define debug TRUE

In meinem bisherigen Code habe ich nur verwendet

#if(debug)
  //code
#endif

aber ist es richtiger zu verwenden?

#ifdef debug
  // code
#endif

Ich habe etwas über Präprozessor-Makros gelesen, aber es machte damals keinen Sinn. Also, ich habe eine Frage: Ist #if defined MACRO gleichwertig #ifdef MACRO? und welches ist besser zum Aktivieren/Deaktivieren eines bestimmten Codeabschnitts?

  • Das scheint zu vergleichen #ifdef mit ifnicht mit #if defined wie der Titel schon sagt.

    – Oliver Charlesworth

    2. September 2016 um 10:21 Uhr

  • Der Unterschied zwischen den beiden ist das #ifdef kann nur eine einzige Bedingung verwenden, while #if defined(NAME) kann zusammengesetzte Bedingungen ausführen.

    – LPs

    2. September 2016 um 10:23 Uhr


  • Übrigens, nach der Bearbeitung ist Ihr Code anders: #if debug prüft ob debug ist wahr, während #ifdef prüft nur, ob debug ist definiert.

    – LPs

    2. September 2016 um 10:28 Uhr


  • unklare Frage: Bitte entscheiden Sie, ob Sie vergleichen #ifdef mit #if defined wie im Titel; oder ob Sie vergleichen #if debug mit #ifdef debug wie in Ihrem Codebeispiel

    – MM

    3. September 2016 um 4:37 Uhr

  • @MM Ich habe eine Korrektur vorgenommen.

    – msc

    3. September 2016 um 4:49 Uhr


#ifdef MACRO
#if defined (MACRO)

werde genau das gleiche machen. Das definierte (MACRO) ist jedoch nur ein Ausdruck, der innerhalb von #if zu 0 oder 1 ausgewertet wird, und es kann mit anderen Ausdrücken kombiniert werden. Zum Beispiel

#if defined (MACRO) && ! defined (MACRO2)
    // Do this
#else
    // Do that
#endif

Versuchen Sie das mit #ifdef – das geht nicht, es sei denn, Ihr Code wird wirklich ungeschickt.

  • defined erfordert keine Klammern. Es hat zwei Formen: defined (identifier) und defined identifier.

    – Kas

    2. September 2016 um 14:10 Uhr


#if defined(MACRO) ist das gleiche wie #ifdef MACRO, ist aber länger. Andererseits erlaubt es, zusätzliche Bedingungen mit hinzuzufügen || oder &&.

#if MACRO ist ähnlich wie #ifdef MACRO aber nicht 100%. Wenn MACRO ist 0 dann #if MACRO wird negativ sein – es erfordert MACRO definiert werden und nicht sein 0. #ifdef prüft nur, ob es auch ohne Wert definiert ist (#define MACRO).

Jetzt ist modern zu bedienen #if und aktivieren/deaktivieren Sie Definitionen mit dem Wert 1 oder 0:

#define FLAG_X 1 // or 0

Benutzer-Avatar
Träumer

Nein, sie sind überhaupt nicht gleichwertig. Ein #if MACRO Zweig wird kompiliert, wenn MACRO wird zu ungleich null ausgewertet. Andererseits ein #ifdef MACRO Zweig wird kompiliert, wenn MACRO ist definiert, egal was es auswertet. So

#include <stdio.h>

#define VAR_SET_TO_TRUE 1
#define VAR_SET_TO_FALSE 0

int main()
{

#if VAR_SET_TO_TRUE
    printf("#if VAR_SET_TO_TRUE\n");
#endif

#if VAR_SET_TO_FALSE
    printf("#if VAR_SET_TO_FALSE\n");
#endif

#if VAR_UNSET
    printf("#if VAR_UNSET\n");
#endif



#ifdef VAR_SET_TO_TRUE
    printf("#ifdef VAR_SET_TO_TRUE\n");
#endif

#ifdef VAR_SET_TO_FALSE
    printf("#ifdef VAR_SET_TO_FALSE\n");
#endif

#ifdef VAR_UNSET
    printf("#ifdef VAR_UNSET\n");
#endif

}

wird ausgegeben

#if VAR_SET_TO_TRUE
#ifdef VAR_SET_TO_TRUE
#ifdef VAR_SET_TO_FALSE

Beachten Sie, dass die Zeile printf("#ifdef VAR_SET_TO_FALSE\n"); Kompiliert wird dabei die Zeile printf("#if VAR_SET_TO_FALSE\n"); ist nicht. Der erste ist kompiliert, weil VAR_SET_TO_FALSE ist definiertobwohl sein Wert ist false.

  • Das OP fragt nach dem Unterschied zwischen #ifdef und #if defined nicht der Unterschied zwischen #if und #if defined – Vielleicht passen Sie Ihre Antwort an diesen Fall an. Auch aus der Erinnerung #if Klauseln werden ausgeführt, wenn RHS nicht null, sondern 1 ergibt.

    – Licht

    2. September 2016 um 16:35 Uhr


Wenn ich Ihre Frage richtig lese, ist der Titel irreführend, sollte es sein

Is #if MACRO equivalent to #ifdef MACRO?

Sie sind nicht äquivalent, aber sie können (und werden oft) beide verwendet, um Binärmodi anzugeben, die entweder ein- oder ausgeschaltet sind. Die Wahl ist meiner Meinung nach eine Frage der persönlichen Präferenz.

Sie verwenden die erste Option und beide haben

#define verbose true

oder

#define verbose false

und überprüfen Sie dann den Modus mit entweder

#if verbose

oder

#if !verbose

Eigentlich würde ich empfehlen, dass Sie entweder TRUE oder 1 anstelle von true und entweder FALSE oder 0 anstelle von false verwenden, da true und false C/C++-Werte sind (oder sein können) und der Präprozessor keinen Zugriff auf C hat /C++-Werte.

Wie auch immer, die andere übliche Möglichkeit, Binärmodi anzugeben, besteht darin, entweder das Flag zu definieren oder es undefiniert zu lassen, in welchem ​​​​Fall Sie beides haben können

#define verbose any thing (including nothing) goes here

oder das #define weglassen.

und dann kannst du testen ob das flag definiert ist, entweder mit

#ifdef verbose

oder sein Äquivalent

#if defined(verbose)

HINWEIS: In diesem Fall testen Sie nicht den Wert des Flags, Sie müssen nur testen, ob er definiert ist.

Wenn es bequemer ist, können Sie auch mit beiden testen, ob das Flag undefiniert ist

#ifndef verbose

oder sein Äquivalent

#if !defined(verbose)

Benutzer-Avatar
Kaz

Wenn wir uns den Kopf genug zerbrechen, können wir einen Unterschied finden. Aber es ist undurchsichtig und beinhaltet undefiniertes Verhalten, also ist es belanglos, wenn wir uns nur darum kümmern, ob der Code strikt ISO C entspricht.

Das #if defined ... Form ist anfällig dafür, sich anders zu verhalten, wenn zuvor a #define defined ... Makro wurde verarbeitet. In der Norm ISO C99 wurde geschrieben, in Bezug auf die #if und #elif Richtlinien:

Vor der Auswertung werden Makroaufrufe in der Liste der Vorverarbeitungstoken, die zum steuernden konstanten Ausdruck werden, ersetzt (mit Ausnahme der Makronamen, die durch den definierten unären Operator geändert werden), genau wie in normalem Text.

Es wird nicht verlangt, dass die defined unärer Operator erkannt und davor geschützt werden, als Makro behandelt zu werden; es ist nur eines der “Vorverarbeitungstokens, die Wille werden der … Ausdruck”. Die defined Betreiber wird in diesem Stadium nur anerkannt, um sein Argument vor Erweiterung zu schützen.

Wenn die Definition von define da ein Makro einfach stehen darf und Vorkommnisse von defined nachträglich ersetzt werden (auch in den Argumenten von #if Vorverarbeitungsanweisungen) und damit stören #if definedohne zu beeinflussen #ifdef.

Vielleicht wurde dieser Bereich der Sprache seit C99 gestrafft.

1365040cookie-checkIst #if defined MACRO äquivalent zu #ifdef MACRO?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy