Frage

Ich versuche, herauszufinden, welche Version von Boost-mein Code denkt, dass es verwendet wird. Ich möchte so etwas wie dies tun:

#error BOOST_VERSION

aber der Präprozessor nicht erweitert BOOST_VERSION.

Ich weiß, dass ich es aus dem Programm zur Laufzeit drucken konnte, und ich weiß, dass ich am Ausgang des Vorprozessors aussehen könnte die Antwort zu finden. Ich fühle mich wie einen Weg, dies mit während der Kompilierung zu tun, könnte nützlich sein.

War es hilfreich?

Lösung

Wenn Sie Visual C ++ verwenden, können Sie #pragma message verwenden:

#include <boost/preprocessor/stringize.hpp>
#pragma message("BOOST_VERSION=" BOOST_PP_STRINGIZE(BOOST_VERSION))

Edit: Dank LB für Link

Offenbar ist die GCC entspricht (nicht getestet):

#pragma message "BOOST_VERSION=" BOOST_PP_STRINGIZE(BOOST_VERSION)

Andere Tipps

BOOST_PP_STRINGIZE scheint eine ausgezeichnete Lösung für C ++, aber nicht für die regelmäßige C.

Hier ist meine Lösung für GNU CPP:

/* Some test definition here */
#define DEFINED_BUT_NO_VALUE
#define DEFINED_INT 3
#define DEFINED_STR "ABC"

/* definition to expand macro then apply to pragma message */
#define VALUE_TO_STRING(x) #x
#define VALUE(x) VALUE_TO_STRING(x)
#define VAR_NAME_VALUE(var) #var "="  VALUE(var)

/* Some example here */
#pragma message(VAR_NAME_VALUE(NOT_DEFINED))
#pragma message(VAR_NAME_VALUE(DEFINED_BUT_NO_VALUE))
#pragma message(VAR_NAME_VALUE(DEFINED_INT))
#pragma message(VAR_NAME_VALUE(DEFINED_STR))

über Definitionen ergeben:

test.c:10:9: note: #pragma message: NOT_DEFINED=NOT_DEFINED
test.c:11:9: note: #pragma message: DEFINED_BUT_NO_VALUE=
test.c:12:9: note: #pragma message: DEFINED_INT=3
test.c:13:9: note: #pragma message: DEFINED_STR="ABC"

"als interger definiert" , "definiert als String" und "definiert, aber kein Wert" Variablen, sie gut funktionieren . Nur für "nicht definiert" Variable, zeigten sie genau die gleichen wie original Variablennamen. Sie haben sich daran gewöhnt -. Oder vielleicht jemand eine bessere Lösung bieten kann

Ich weiß, dass dies eine lange Zeit nach der ursprünglichen Abfrage, aber immer noch nützlich sein kann.

Dies kann in GCC mit dem stringify Operator "#" getan werden, aber es erfordert zwei Stufen.

#define XSTR(x) STR(x)
#define STR(x) #x

Der Wert eines Makro kann dann mit angezeigt werden:

#pragma message "The value of ABC: " XSTR(ABC)

Siehe auch:. 3.4 Stringification in der gcc Online-Dokumentation

Wie es funktioniert:

Der Präprozessor versteht Strings in Anführungszeichen und behandelt sie anders als normalen Text. String-Verkettung ist ein Beispiel für diese besondere Behandlung. Die Nachricht Pragma erfordert ein Argument, das eine Zeichenfolge in Anführungszeichen ist. Wenn es mehr als eine Komponente für das Argument ist, dann müssen sie alle Strings sein, so dass die String-Verkettung angewendet werden. Der Präprozessor kann nie davon ausgehen, dass ein String ohne Anführungszeichen behandelt werden soll, als ob sie zitiert wurden. Wenn ja, dann:

#define ABC 123
int n = ABC;

würde nicht kompiliert werden.

Nun betrachten:

#define ABC abc
#pragma message "The value of ABC is: " ABC

, die

entspricht
#pragma message "The value of ABC is: " abc

Dies führt zu einer Präprozessor Warnung, weil abc (unquoted) nicht mit dem vorhergehenden Zeichenfolge verkettet werden.

Betrachten wir nun den Präprozessor stringize (die einst stringification genannt wurde, haben Sie die Links in der Dokumentation geändert worden, um die überarbeitete Terminologie zu reflektieren. (Beide Begriffe sind übrigens ebenso abscheulich. Die korrekte Bezeichnung ist natürlich, stringifaction. Seien bereit, Ihre Links zu aktualisieren.)) Operator. Dies wirkt sich nur auf die Argumente eines Makros und ersetzt die nicht expandierten Argument mit dem Argument in doppelte Anführungszeichen eingeschlossen. Also:

#define STR(x) #x
char *s1 = "abc";
char *s2 = STR(abc);

identische Werte s1 und s2 zuweisen. Wenn Sie gcc laufen -E können Sie dies in der Ausgabe sehen. Vielleicht wäre STR besser etwas wie enquote genannt werden.

Das löst das Problem der Anführungszeichen um einen nicht notierten Punkt setzen, jetzt das Problem ist, dass, wenn das Argument ein Makro ist, wird das Makro nicht erweitert werden. Aus diesem Grund ist das zweite Makro benötigt wird. XSTR erweitert sein Argument, dann STR ruft den erweiterten Wert in Anführungszeichen gesetzt werden.

Soweit ich weiß '#error' werden nur Strings drucken, in der Tat Sie don ‚t sogar müssen Verwendung Anführungszeichen .

Haben Sie verschiedenen gezielt falschen Code versucht, das Schreiben mit „BOOST_VERSION“? Vielleicht so etwas wie "blah [BOOST_VERSION] = foo;" wird Ihnen sagen, so etwas wie „Stringliteral 1.2.1 kann nicht als Array-Adresse verwendet werden“. Es wird keine schöne Fehlermeldung, aber zumindest werden sie Ihnen den entsprechenden Wert an. Sie können spielen, bis Sie einen Compiler-Fehler finden, dass Sie den Wert nicht sagen.

Ohne boost:

  1. definieren wieder gleiche Makro- und Compiler HIMSELF Warnung geben wird.

  2. Von warnen Sie Standort der vorherigen Definition sehen.

  3. vi Datei der vorherigen Definition.

ambarish@axiom:~/cpp$ g++ shiftOper.cpp
shiftOper.cpp:7:1: warning: "LINUX_VERSION_CODE" redefined
shiftOper.cpp:6:1: warning: this is the location of the previous definition

#define LINUX_VERSION_CODE 265216
#define LINUX_VERSION_CODE 666

int main ()
{

}
#define a <::BOOST_VERSION>
#include a
MSVC2015 : fatal error C1083: kann nicht geöffnet werden Include-Datei: ':: 106200': Keine solche Datei oder das Verzeichnis

funktioniert auch, wenn preprocess to file aktiviert ist, auch wenn ungültige Token vorhanden sind:

#define a <::'*/`#>
#include a
MSVC2015 : fatal error C1083: kann nicht geöffnet werden Include-Datei: '::' * / '#': Keine solche Datei oder das Verzeichnis
GCC4.x : Warnung: fehlende Abschluss 'Zeichen [-Winvalid-pp-Token]
    define a <:: '* /' #>

In Microsoft C / C ++, können Sie die eingebauten in _CRT_STRINGIZE() verwenden Konstanten zu drucken. Viele meiner stdafx.h Dateien enthalten eine Kombination aus diesen:

#pragma message("_MSC_VER      is " _CRT_STRINGIZE(_MSC_VER))
#pragma message("_MFC_VER      is " _CRT_STRINGIZE(_MFC_VER))
#pragma message("_ATL_VER      is " _CRT_STRINGIZE(_ATL_VER))
#pragma message("WINVER        is " _CRT_STRINGIZE(WINVER))
#pragma message("_WIN32_WINNT  is " _CRT_STRINGIZE(_WIN32_WINNT))
#pragma message("_WIN32_IE     is " _CRT_STRINGIZE(_WIN32_IE))
#pragma message("NTDDI_VERSION is " _CRT_STRINGIZE(NTDDI_VERSION)) 

und gibt so etwas wie folgt aus:

_MSC_VER      is 1915
_MFC_VER      is 0x0E00
_ATL_VER      is 0x0E00
WINVER        is 0x0600
_WIN32_WINNT  is 0x0600
_WIN32_IE     is 0x0700
NTDDI_VERSION is 0x06000000

Sie können auch die Quelldatei vorverarbeiten und sehen, was die Präprozessor Wert auswertet zu.

Suchen Sie

#if BOOST_VERSION != "1.2"
#error "Bad version"
#endif

Nicht toll, wenn BOOST_VERSION ein String ist, wie ich angenommen habe, aber auch einzelne Zahlen für die Haupt-, Neben- und Revisionsnummern definiert werden kann.

am Ausgang des Vorprozessors der Suche ist die nächste Sache, die Antwort, die Sie fragen.

Ich weiß, Sie ausgeschlossen haben, dass (und andere Arten), aber ich bin mir nicht sicher, warum. Sie haben ein spezifisch genug, um Problem zu lösen, aber Sie haben nicht erklärt, warum eine der „normalen“ Methoden für Sie nicht gut funktionieren.

Sie können ein Programm schreiben, die Drucke aus BOOST_VERSION und Kompilierung und es als Teil Ihres Build-System ausgeführt werden. Ansonsten denke ich, Sie Glück unterwegs sind.

BOOST_VERSION wird in der Boost-Header-Datei version.hpp definiert.

Werfen Sie einen Blick auf die Boost-Dokumentation als auch in Bezug auf, wie Sie das Makro verwenden:

In Bezug auf BOOST_VERSION von http://www.boost.org/doc/libs/1_37_0/libs/config/doc/html/boost_config/boost_macro_reference.html#boost_config.boost_macro_reference.boost_helper_macros :

  

Beschreibt die Boost-Versionsnummer in   Xxyyzz Format, so dass:    (BOOST_VERSION % 100) ist der Sub-Moll   Version, ((BOOST_VERSION / 100) %    1000) ist die kleinere Version, und    (BOOST_VERSION / 100000) ist die Haupt   Version.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top