2016-02-24 7 views
10

Ich mag würde den folgenden Präprozessor verwenden definiert:Wie entferne ich einen C-Style-Cast aus #define, damit ich ihn in einem Präprozessor #if verwenden kann?

[3. Kopf Partei (nicht ändern)]

#define SWCI_VERSION_MAJOR    (unsigned char) 4 
#define SWCI_VERSION_MINOR    (unsigned char) 16 

Wenn sie auf diese Weise verglichen werden:

[meine Implementierung]

#if SWCI_VERSION_MAJOR >= 4 && SWCI_VERSION_MINOR >= 16 

Dann erhalte ich:

schwerwiegender Fehler C1017: ungültige Integer-Konstante Ausdruck

Ich habe bemerkt, dass, wenn ich sie ohne (unsigned char) definieren wird die Richtlinie angenommen, aber ich habe keinen Zugriff auf die definiert, so würde Ich mag um das Problem möglichst zu umgehen.

+1

Mögliche Duplikat [was bedeutet der Compiler-Fehler "missing Binäroperators vor Token" bedeuten?] (Http://stackoverflow.com/questions/21338385/what-does-the-compiler-error- missing-binary-operator-vor-token-mean) – BoBTFish

+3

Beachten Sie, dass die Fehlermeldung unterscheidet sich von http://stackoverflow.com/q/21338385/1171191, weil es ein anderer Compiler ist, aber der Fehler ist der gleiche: Sie können ' t wirft ein '# if', weil es im Präprozessor nicht passiert, wie AShellys Antwort erklärt. – BoBTFish

+0

@ j4nSolo Wenn Sie es so vergleichen, wie Sie es erwähnt haben, was hindert Sie daran, die MACROS ohne (unsigned char) zu definieren? –

Antwort

13

Sie können dies mit ein wenig Präprozessor Magie zu arbeiten. Aufgrund der Art, wie der Präprozessor Makros anwendet, können Sie manchmal einige Änderungen vornehmen, indem Sie mehrere Makro-Ebenen verwenden. Boost.Preprocess nutzt dieses Verhalten. Dieser Code nutzt die Tatsache, dass (unsigned char) aussieht wie in einen Makroaufruf gemacht werden kann, indem der Makroname X vorangestellt wird, der nichts auswertet und nur die nachfolgende Zahl zurücklässt.

#define SWCI_VERSION_MAJOR    (unsigned char) 4 
#define SWCI_VERSION_MINOR    (unsigned char) 16 

#define X(unused) 
#define APPLY(x) x 

#define MAJOR (APPLY(X SWCI_VERSION_MAJOR)) 
#define MINOR (APPLY(X SWCI_VERSION_MINOR)) 

#if MAJOR >= 4 && MINOR >= 16 
#error "Version is greater or equal to 4.16" 
#endif 

Siehe https://goo.gl/GOsLDL für ein Beispiel des #if wahre Auswertung und Drucken der #error Botschaft, die ich hinzugefügt.

+0

Danke, das hat endlich funktioniert! Hinweis: APPLY2 ist nicht notwendig, da es nur mit einem Helfer funktioniert. – j4nSolo

+0

@ j4nSolo Froh, dass es funktioniert hat und danke, dass du mich über 'APPLY2' informiert hast. Ich habe eine Änderung eingereicht, um sie zu entfernen. –

+0

Das ist so hässlich, es ist wunderschön! – TonyK

-2

Man denke nur an dem folgenden

#define SWCI_VERSION_MAJOR    (unsigned char) 4 
#define SWCI_VERSION_MINOR    (unsigned char) 16 

Wenn in dem folgenden Ausdruck verwendet:

#if SWCI_VERSION_MAJOR >= 4 && SWCI_VERSION_MINOR >= 16 

Diese (von Preprocessor) umgewandelt wird auf dem folgenden #if (unsigned char) 4> 4

Das Problem ist, dass dieser Ausdruck (unsigned char) 4> 4 scheint falsch zu sein.

Wenn Sie keine 3rd-Party-Header-Dateien ändern, können Sie versuchen

#undef SWCI_VERSION_MAJOR 

zu verwenden, aber dies hängt stark von #include, um

+4

Wenn ich definiere, kann ich ihre Werte nicht verwenden. Das ist das Gegenteil von dem, was ich erreichen möchte. – j4nSolo

+0

Sie können undef und dann definieren Sie es richtig (mit Klammern). Hier ist, was ich meine: include1.h '#define SWCI_VERSION_MAJOR (unsigned char) 4' ' #define SWCI_VERSION_MINOR (unsigned char) 16' includeA.h ' #if SWCI_VERSION_MAJOR> = 4 && SWCI_VERSION_MINOR> = 16' 'do_something_if_version_is_as_expected() ' # endif' your.cpp '#include "include1.h"' ' #undef SWCI_VERSION_MAJOR' ' #undef SWCI_VERSION_MINOR' '#define SWCI_VERSION_MAJOR ((unsigned char) 4) ' ' #define SWCI_VERSION_MINOR ((unsigned char) 16) ' Ihr Code – rezdm

+0

... Sorry Formatierung ging schief. Die Idee ist es, .h, wo diese Definition definiert ist, einzuschließen und dann in Ihrer .c/.cpp undefined und richtig zu definieren. – rezdm

0

Das Problem ist, dass Sie nicht dieses Makros als richtige Zahlen verwenden können . Je nachdem, was Sie im Inneren des if Block zu tun, können Sie es für eine nicht-vorverarbeitet Aussage:

// Note the next line does not start with a # 
if((unsigned int)SWCI_VERSION_MAJOR >= 4 && (unsigned int)SWCI_VERSION_MINOR >= 16) 
{ 
    // ... 
} 

aber das funktioniert nur natürlich, wenn Sie es in einer Funktion und den Inhalt des if verwenden Block sind keine Präprozessoranweisungen wie s.

2

Vielleicht hilft eine constexpr-Funktion?So etwas wie

constexpr bool version_supported(const char major, const char minor) 
{ 
    return major >= 4 && minor >= 16; 
} 
constexpr VERSION_SUPPORTED = version_supported(SWCI_VERSION_MAJOR, SWCI_VERSION_MINOR);