Question

Je suis en train de comprendre quelle version de Boost mon code pense qu'il utilise. Je veux faire quelque chose comme ceci:

#error BOOST_VERSION

mais le préprocesseur ne se développe pas BOOST_VERSION.

Je sais que je pourrais l'imprimer à l'exécution du programme, et je sais que je pourrais regarder la sortie du préprocesseur pour trouver la réponse. Je me sens comme avoir une façon de le faire lors de la compilation pourrait être utile.

Était-ce utile?

La solution

Si vous utilisez Visual C ++, vous pouvez utiliser #pragma message:

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

Modifier Merci à LB pour lien

Apparemment, l'équivalent du CCG (non testé):

#pragma message "BOOST_VERSION=" BOOST_PP_STRINGIZE(BOOST_VERSION)

Autres conseils

BOOST_PP_STRINGIZE semble une excellente solution pour C ++, mais pas pour régulier C.

Voici ma solution pour 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))

définitions ci-dessus donnent lieu à:

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"

"défini comme interger" , "défini comme chaîne" et "défini mais aucune valeur" les variables, ils fonctionnent très bien . Seulement pour les « non défini » variables, ils affichent exactement le même que le nom variable d'origine. Vous devez habituer -. Ou peut-être quelqu'un peut fournir une meilleure solution

Je sais que cela est longtemps après la requête initiale, mais cela peut encore être utile.

Cela peut être fait à l'aide de l'opérateur GCC stringify « # », mais il nécessite deux étapes.

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

La valeur d'une macro peut alors être affiché avec:

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

Voir:. 3.4 dans la documentation mise en chaîne en ligne gcc

Comment ça marche:

Le préprocesseur comprend les chaînes entre guillemets et les traite différemment du texte normal. concaténation de chaîne est un exemple de ce traitement spécial. Le pragma message requiert un argument qui est une chaîne entre guillemets. Quand il y a plus d'un composant à l'argument alors ils doivent tous être des chaînes de sorte que la concaténation de chaîne peut être appliquée. Le préprocesseur ne peut jamais supposer qu'une chaîne non protégée doit être traitée comme si elle était cité. Si elle l'a fait alors:

#define ABC 123
int n = ABC;

ne compilerait pas.

Considérons maintenant:

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

qui est équivalent à

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

Cela provoque un avertissement de préprocesseur parce que abc (sans guillemets) ne peut pas être concaténé avec la chaîne précédente.

Considérons maintenant le préprocesseur stringize (qui était autrefois appelé mise en chaîne, les liens dans la documentation ont été modifiés pour refléter la nouvelle terminologie. (Les deux termes, soit dit en passant, sont également haïssable. Le terme correct est, bien sûr, stringifaction. Soyez prêt à mettre à jour vos liens.)) opérateur. Cela agit uniquement sur les arguments d'une macro et remplace l'argument non dilatée avec l'argument entre guillemets. Ainsi:

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

va attribuer des valeurs identiques à s1 et s2. Si vous exécutez gcc -E vous pouvez le voir dans la sortie. Peut-être STR serait mieux nommé quelque chose comme ENQUOTE.

Cela résout le problème de mettre des guillemets autour d'un élément non protégé, le problème est maintenant que, si l'argument est une macro, la macro ne sera pas élargi. Voilà pourquoi la deuxième macro est nécessaire. Xstr élargit son argument, puis appelle STR de mettre la valeur en expansion entre guillemets.

Pour autant que je sais « #error » n'imprime des chaînes, en fait vous n « t ont même besoin d'utiliser des guillemets .

Avez-vous essayé d'écrire différents codes en utilisant délibérément incorrect « BOOST_VERSION »? Peut-être quelque chose comme "bla [BOOST_VERSION] = foo;" vous dira quelque chose comme « 1.2.1 littéral de chaîne ne peut pas être utilisé comme une adresse de tableau ». Il ne sera pas un joli message d'erreur, mais au moins ça va vous montrer la valeur pertinente. Vous pouvez jouer jusqu'à ce que vous trouvez une erreur de compilation qui ne vous dira la valeur.

Sans boost:

  1. définir à nouveau même macro et compilateur donnera avertissement LUI-MÊME.

  2. De avertissement vous pouvez voir l'emplacement de la définition précédente.

  3. fichier vi de la définition précédente.

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 : C1083 erreur fatale: Impossible d'ouvrir le fichier à inclure: ':: 106200': Aucun fichier ou répertoire

fonctionne même si preprocess to file est activée, même si des jetons non valides sont présents:

#define a <::'*/`#>
#include a
MSVC2015 : erreur fatale C1083: Impossible d'ouvrir le fichier include: '::' * / '#': Aucun fichier ou répertoire
GCC4.x : avertissement: manque de terminaison "caractère [-Winvalid-pp-token]
    #define a <:: '* / `#>

Dans Microsoft C / C ++, vous pouvez utiliser le haut-_CRT_STRINGIZE() pour imprimer des constantes. Beaucoup de mes fichiers contiennent stdafx.h une combinaison de celles-ci:

#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)) 

et sorties quelque chose comme ceci:

_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

Vous pouvez également prétraiter le fichier source et voir ce que la valeur de préprocesseur évalue à.

Vous cherchez

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

Non Si BOOST_VERSION est une chaîne, comme je l'ai supposé, mais il peut aussi être des nombres entiers individuels définis pour les grands, les numéros mineurs et de révision.

En regardant la sortie du préprocesseur est la chose la plus proche de la réponse que vous demandez.

Je sais que vous avez exclu que (et d'autres moyens), mais je ne sais pas pourquoi. Vous avez un problème assez précis pour résoudre, mais vous ne l'avez pas expliqué pourquoi l'une des méthodes « normales » ne fonctionnent pas bien pour vous.

Vous pouvez écrire un programme qui imprime BOOST_VERSION et compiler et exécuter dans le cadre de votre système de construction. Sinon, je pense que vous êtes hors de la chance.

BOOST_VERSION est défini dans le fichier d'en-tête de boost version.hpp.

Jetez un oeil à la documentation Boost ainsi, en ce qui concerne la façon dont vous utilisez la macro:

En ce qui concerne BOOST_VERSION, 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 :

  

Décrit le numéro de version de coup de pouce   format xxyyzz tel que:    (BOOST_VERSION % 100) est le sous-mineur   version ((BOOST_VERSION / 100) %    1000) est la version mineure, et    (BOOST_VERSION / 100000) est le principal   la version.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top