#ifdef in #define

80

Ich versuche so etwas zu schreiben:

#define COV_ON(x) \
                #ifdef COVERAGE_TOOL \
                    _Pragma (COVERAGE #x)
                #endif

Gibt es eine Möglichkeit, dies zu definieren COV_ON? Ich weiß, was ich oben getan habe, ist falsch, da ich nicht #ifdefin #define haben kann. ( #ist kein zulässiges Zeichen in #define). Gibt es also eine Lösung?

agent.smith
quelle
1
Alle Antworten hier scheinen die Verwendung von do {} while(0)(oder einer gleichwertigen) zu vermeiden, um eine leere Aussage zu vermeiden. Siehe meine Antwort auf das verknüpfte Duplikat
Roger Lipscombe

Antworten:

87

Nicht möglich. Mach es umgekehrt:

#ifdef COVERAGE_TOOL
#define COV_ON(x) _Pragma (COVERAGE #x)
#else
#define COV_ON(x)
#endif
Hans Passant
quelle
21

Einfach umdrehen:

#ifdef COVERAGE_TOOL
#define COV_ON(x) _Pragma (COVERAGE #x)
#else
#define COV_ON(x) /* foo */
#endif
Philip
quelle
Danke für deine Antwort. Ich habe COV_ON (ein) und COV_ON (aus) ausprobiert, aber dann erhalte ich eine Fehlermeldung mit der Meldung Fehler: erwartet ')', fast aus. Irgendeine Idee über das Problem.
Agent.smith
Sie sind Saiten. Muss ich sie als reguläre Zeichenfolgen im Anführungszeichen verwenden? Wie "Ein" und "Aus".
Agent.smith
Es hängt von Ihrer Definition von COVERAGE ab, aber ich würde vermuten, dass Sie sie zitieren müssen. Ich schlage vor, dass Sie eine weitere Frage für diese neue Ausgabe öffnen.
Philip
Ich habe es mit Zitaten versucht, aber ohne Nutzen. Ich habe bereits einen neuen Thread eröffnet. Lassen Sie mich wissen, wenn Sie der Meinung sind, dass die Syntax für _Pragma falsch ist.
Agent.smith
13

Dies ist eine alte Frage, aber sie brauchte eine aktuelle Antwort.

Anstatt ein Inline-ifdef innerhalb des Makros zu verwenden, können Sie selektiv ein __VA_ARGS__Makro definieren , um dasselbe zu tun

#ifdef COVERAGE_TOOL
#define IF_COVERAGE_TOOL(...) __VA_ARGS__
#else
#define IF_COVERAGE_TOOL(...)
#endif
#define COV_ON(x) IF_COVERAGE_TOOL( _Pragma (COVERAGE #x) )

Dies hat eine ähnliche Funktionalität wie ein ifdef, außer dass Sie Klammern erhalten, um den Anfang und das Ende abzugrenzen (die meisten IDEs haben keine Probleme beim Code-Folding). Sie können zwar weiterhin #defineund #ifdefinnerhalb des Kontexts verwenden, dies #includeist jedoch nicht zulässig. Um ähnliche Inline-Funktionen zu erhalten #else, können Sie ein entsprechendes Makro wie folgt definieren:

//#define FOO
#ifdef FOO
#define IF_FOO(...) __VA_ARGS__ 
#define NO_FOO(...)
#else
#define IF_FOO(...)
#define NO_FOO(...) __VA_ARGS__
#endif

IF_FOO(
  #define BAR 5
  int foo = BAR;
)
NO_FOO(
  #define foo 5
)

Nur einer von NO_FOO()/IF_FOOwird Code erzeugen.

OK, das ist ein handliches Hack, aber wir können es machen MEHR nützlicher als #ifdefs... Boolesche Logik und vielleicht Konfiguration? Lassen Sie uns einige Wahrheitstabellen (und ein paar Hilfsmakros) einrichten.

#define PASTE_(x,y) x##y
#define PASTE(x,y) PASTE_(x,y)
#define PASTE3_(x,y,z) x##y##z
#define PASTE3(x,y,z) PASTE3_(x,y,z)
#define Y(...) __VA_ARGS__
#define N(...)
#define IF(x) x //alternate method similar to IFNOT()

#define NOT_N Y
#define NOT_Y N
#define IF_NOT(x) PASTE(NOT_,x)
#define NOT(x) PASTE(NOT_,x)

#define N_OR_N N
#define N_OR_Y Y
#define Y_OR_N Y
#define Y_OR_Y Y
#define OR(x,y) PASTE3(x,_OR_,y)

#define N_AND_N N
#define N_AND_Y N
#define Y_AND_N N
#define Y_AND_Y Y
#define AND(x,y) PASTE3(x,_AND_,y)

#define N_XOR_N N
#define N_XOR_Y Y
#define Y_XOR_N Y
#define Y_XOR_Y N
#define XOR(x,y) PASTE3(x,_XOR_,y)

#define N_NOR_N Y
#define N_NOR_Y N
#define Y_NOR_N N
#define Y_NOR_Y N
#define NOR(x,y) PASTE3(x,_NOR_,y)

#define N_NAND_N Y
#define N_NAND_Y Y
#define Y_NAND_N Y
#define Y_NAND_Y N
#define NAND(x,y) PASTE3(x,_NAND_,y)

#define N_XNOR_N Y
#define N_XNOR_Y N
#define Y_XNOR_N N
#define Y_XNOR_Y Y
#define XNOR(x,y) PASTE3(x,_XNOR_,y)

#define IF2(x,y,z) PASTE3(x,y,z)

config.h

#define FOO Y
#define BAR N
#define BAZ Y

code.c

AND(FOO,BAR)(/*do stuff if both FOO and BAR are enabled*/)
IF2(FOO,_AND_,BAR)( /*do stuff if both FOO and BAR are enabled*/ )
OR(BAZ,AND(FOO,BAR))(
  /*do stuff if both FOO and BAR are enabled or BAZ is enabled*/
)
Technosaurus
quelle
Ich mag deinen Stil (=
étale-kohomology
6
#ifdef COVERAGE_TOOL
    #define COV_ON(x) _Pragma (COVERAGE #x)
#else
    #define COV_ON(x)
#endif
EboMike
quelle
6

Du kannst nicht. Aber Sie können tauschen #ifdefund #define:

#ifdef COVERAGE_TOOL
#   define COV_ON(x) _Pragma (COVERAGE #x)
#else
#   define COV_ON(x)
#endif
Sam Hocevar
quelle
Danke für deine Antwort. Ich habe COV_ON (ein) und COV_ON (aus) ausprobiert, aber dann erhalte ich eine Fehlermeldung mit der Meldung Fehler: erwartet ')', fast aus. Irgendeine Idee über das Problem.
Agent.smith
Ohne Ihren Compiler zu kennen, müssten wir die erwartete _PragmaSyntax kennen. Wie würden Sie es ohne ein Makro machen?
Sam Hocevar
Ich verwende den VC2005-Compiler und habe die _Pragma-Syntax online gesehen. Ich habe #pragma noch nie so benutzt.
Agent.smith
Dann brauchen Sie einen Stringify-Hack. Siehe diese Frage und Antwort .
Sam Hocevar
Ich denke, das Problem ist VC2005. Sie verwenden nicht _Pragma, sondern __pragma. Ich bin mir nicht sicher, aber es sieht so aus. Aber ich bekomme immer noch ein unbekanntes Pragma mit __pragma.
Agent.smith
3

Wie Sie bereits erwähnt haben, ist es nicht möglich, ein #ifdef in einem #define zu haben. Stattdessen sollten Sie die Reihenfolge umkehren:

#ifdef COVERAGE_TOOL \
  #define COV_ON(x) \
    etc.
#endif
jberg
quelle