Ich versuche herauszufinden, welche Version von Boost mein Code verwendet. Ich möchte so etwas machen:
#error BOOST_VERSION
Der Präprozessor erweitert BOOST_VERSION jedoch nicht.
Ich weiß, dass ich es zur Laufzeit aus dem Programm ausdrucken kann, und ich weiß, dass ich die Ausgabe des Präprozessors überprüfen kann, um die Antwort zu finden. Ich denke, eine Möglichkeit, dies während der Kompilierung zu tun, könnte nützlich sein.
macros
c-preprocessor
boost-preprocessor
Jim Hunziker
quelle
quelle
Antworten:
Ich weiß, dass dies eine lange Zeit nach der ursprünglichen Abfrage ist, aber dies kann immer noch nützlich sein.
Dies kann in GCC mit dem Stringify-Operator "#" erfolgen, erfordert jedoch zwei Stufen.
Der Wert eines Makros kann dann angezeigt werden mit:
Siehe: 3.4 Stringifizierung in der gcc Online-Dokumentation.
Wie es funktioniert:
Der Präprozessor versteht Zeichenfolgen in Anführungszeichen und behandelt sie anders als normalen Text. Die Verkettung von Zeichenfolgen ist ein Beispiel für diese spezielle Behandlung. Das Nachrichtenpragma erfordert ein Argument, das eine Zeichenfolge in Anführungszeichen ist. Wenn das Argument mehr als eine Komponente enthält, müssen alle Zeichenfolgen sein, damit die Verkettung von Zeichenfolgen angewendet werden kann. Der Präprozessor kann niemals davon ausgehen, dass eine nicht in Anführungszeichen gesetzte Zeichenfolge so behandelt werden sollte, als ob sie in Anführungszeichen gesetzt wäre. Wenn ja, dann:
würde nicht kompilieren.
Betrachten Sie nun:
das ist äquivalent zu
Dies führt zu einer Präprozessorwarnung, da abc (nicht in Anführungszeichen) nicht mit der vorhergehenden Zeichenfolge verkettet werden kann.
Betrachten Sie nun die Präprozessor-Stringisierung (die früher als Stringifizierung bezeichnet wurde). Die Links in der Dokumentation wurden geändert, um die überarbeitete Terminologie widerzuspiegeln. (Beide Begriffe sind übrigens gleichermaßen verabscheuungswürdig. Der richtige Begriff ist natürlich Stringifaction. Seien Sie bereit für die Aktualisierung Ihre Links.)) Betreiber. Dies wirkt sich nur auf die Argumente eines Makros aus und ersetzt das nicht erweiterte Argument durch das in doppelte Anführungszeichen eingeschlossene Argument. So:
weist s1 und s2 identische Werte zu. Wenn Sie gcc -E ausführen, können Sie dies in der Ausgabe sehen. Vielleicht würde STR besser so etwas wie ENQUOTE heißen.
Dies löst das Problem, Anführungszeichen um ein nicht in Anführungszeichen gesetztes Element zu setzen. Das Problem besteht nun darin, dass das Makro nicht erweitert wird, wenn das Argument ein Makro ist. Aus diesem Grund wird das zweite Makro benötigt. XSTR erweitert sein Argument und ruft dann STR auf, um den erweiterten Wert in Anführungszeichen zu setzen.
quelle
__IPHONE_9_3
. B. durch Ersetzen von ABC durch .BOOST_PP_STRINGIZE
scheint eine ausgezeichnete Lösung für C ++ zu sein, aber nicht für reguläres C.Hier ist meine Lösung für GNU CPP:
Die obigen Definitionen führen zu:
Für die Variablen "definiert als Interger" , "definiert als Zeichenfolge" und "definiert, aber kein Wert" funktionieren sie einwandfrei . Nur für "nicht definierte" Variablen werden sie genauso angezeigt wie der ursprüngliche Variablenname. Man muss sich daran gewöhnen - oder vielleicht kann jemand eine bessere Lösung anbieten.
quelle
DEFINED_INT=(sizeof(MY_STRUCT))
, ohne dass dersizeof
Operator ausgewertet wird.sizeof
, aber immer noch neugierig ist, ob es einen cleveren Weg gibt, dies zu erreichen.)#define masks {0xff, 0xaf, 0x0f}
Wenn Sie Visual C ++ verwenden, können Sie Folgendes verwenden
#pragma message
:Edit: Danke an LB für den Link
Anscheinend ist das GCC-Äquivalent (nicht getestet):
quelle
BOOST_PP_STRINGIZE
einfügen würden, die nett und kurz und kopierbar / einfügbar ist.Soweit ich weiß, druckt '#error' nur Zeichenfolgen, Sie müssen nicht einmal Anführungszeichen verwenden .
Haben Sie versucht, mit "BOOST_VERSION" verschiedene absichtlich falsche Codes zu schreiben? Vielleicht so etwas wie "bla [BOOST_VERSION] = foo;" wird Ihnen etwas sagen wie "String-Literal 1.2.1 kann nicht als Array-Adresse verwendet werden". Es wird keine hübsche Fehlermeldung sein, aber es zeigt Ihnen zumindest den relevanten Wert. Sie können herumspielen, bis Sie einen Kompilierungsfehler finden, der Ihnen den Wert angibt.
quelle
std::vector<BOOST_VERSION>;
in gcc 4.4.1. Vielen Dank!Ohne Schub:
Definieren Sie dasselbe Makro erneut und der Compiler HIMSELF gibt eine Warnung aus.
Aus der Warnung können Sie den Ort der vorherigen Definition ersehen.
vi-Datei der vorherigen Definition.
quelle
__cplusplus
.In Microsoft C / C ++ können Sie die integrierten Funktionen
_CRT_STRINGIZE()
zum Drucken von Konstanten verwenden. Viele meinerstdafx.h
Dateien enthalten eine Kombination davon:und gibt so etwas aus:
quelle
Funktioniert auch, wenn
preprocess to file
es aktiviert ist, auch wenn ungültige Token vorhanden sind:quelle
Build error: #include expects "FILENAME" or <FILENAME>
. Seufzer.'
:*** WARNING C318 IN LINE 2 OF test.c: can't open file '::*/`'
Sie können auch die Quelldatei vorverarbeiten und sehen, wie der Präprozessorwert ausgewertet wird.
quelle
Suchen Sie
Nicht großartig, wenn BOOST_VERSION eine Zeichenfolge ist, wie ich angenommen habe, aber es können auch einzelne Ganzzahlen für die Haupt-, Neben- und Revisionsnummern definiert sein.
quelle
#if VARIABLE == 123
Anweisung im laufenden Betrieb ändern und die Syntaxhervorhebung sagt mir, ob es der Wert ist, von dem ich denke, dass er es ist oder nicht ...Ein Blick auf die Ausgabe des Präprozessors kommt der von Ihnen gewünschten Antwort am nächsten.
Ich weiß, dass Sie das (und andere Möglichkeiten) ausgeschlossen haben, aber ich bin mir nicht sicher, warum. Sie haben ein Problem, das spezifisch genug ist, um es zu lösen, aber Sie haben nicht erklärt, warum eine der "normalen" Methoden für Sie nicht gut funktioniert.
quelle
Sie können ein Programm schreiben, das es ausgibt,
BOOST_VERSION
kompiliert und als Teil Ihres Build-Systems ausführt . Ansonsten denke ich, dass Sie kein Glück haben.quelle
BOOST_VERSION ist in der Boost-Header-Datei version.hpp definiert.
quelle
Schauen Sie sich auch die Boost-Dokumentation an, um zu erfahren, wie Sie das Makro verwenden:
In Bezug auf die
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 :quelle
Versuchen Sie anstelle von #error, das Makro kurz vor seiner Verwendung neu zu definieren. Die Kompilierung schlägt fehl und der Compiler gibt den aktuellen Wert an, der seiner Meinung nach für das Makro gilt.
#define BOOST_VERSION bla
quelle