J'essaie de comprendre quelle version de Boost mon code pense qu'il utilise. Je veux faire quelque chose comme ça:
#error BOOST_VERSION
mais le préprocesseur ne développe pas BOOST_VERSION.
Je sais que je pourrais l'imprimer au moment de l'exécution à partir du programme, et je sais que je pourrais regarder la sortie du préprocesseur pour trouver la réponse. J'ai le sentiment qu'avoir un moyen de faire cela pendant la compilation pourrait être utile.
macros
c-preprocessor
boost-preprocessor
Jim Hunziker
la source
la source
Réponses:
Je sais que c'est longtemps après la requête d'origine, mais cela peut encore être utile.
Cela peut être fait dans GCC en utilisant l'opérateur stringify "#", mais cela nécessite deux étapes.
La valeur d'une macro peut alors être affichée avec:
Voir: 3.4 Stringification dans la documentation en ligne de gcc.
Comment ça fonctionne:
Le préprocesseur comprend les chaînes entre guillemets et les gère différemment du texte normal. La concaténation de chaînes est un exemple de ce traitement spécial. Le pragma de message nécessite un argument qui est une chaîne entre guillemets. Lorsqu'il y a plus d'un composant à l'argument, ils doivent tous être des chaînes pour que la concaténation de chaînes puisse être appliquée. Le préprocesseur ne peut jamais supposer qu'une chaîne sans guillemets doit être traitée comme si elle était entre guillemets. Si c'est le cas, alors:
ne compilerait pas.
Considérez maintenant:
ce qui équivaut à
Cela provoque un avertissement du préprocesseur car 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é stringification, les liens dans la documentation ont été modifiés pour refléter la terminologie révisée. (Les deux termes, d'ailleurs, sont tout aussi détestables. Le terme correct est, bien sûr, stringifaction. Soyez prêt à mettre à jour vos liens.)) opérateur. Cela n'agit que sur les arguments d'une macro et remplace l'argument non développé par l'argument entre guillemets. Donc:
attribuera des valeurs identiques à s1 et s2. Si vous exécutez gcc -E, vous pouvez le voir dans la sortie. Peut-être que STR serait mieux nommé quelque chose comme ENQUOTE.
Cela résout le problème de placer des guillemets autour d'un élément sans guillemets, le problème est maintenant que, si l'argument est une macro, la macro ne sera pas développée. C'est pourquoi la deuxième macro est nécessaire. XSTR développe son argument, puis appelle STR pour mettre la valeur développée entre guillemets.
la source
__IPHONE_9_3
.BOOST_PP_STRINGIZE
semble une excellente solution pour C ++, mais pas pour C.Voici ma solution pour GNU CPP:
Les définitions ci-dessus donnent:
Pour les variables "défini comme entier" , "défini comme chaîne" et "défini mais pas de valeur" , ils fonctionnent très bien. Uniquement pour la variable "non définie" , ils affichent exactement le même nom que le nom de la variable d'origine. Vous devez vous y habituer - ou peut-être que quelqu'un peut fournir une meilleure solution.
la source
DEFINED_INT=(sizeof(MY_STRUCT))
, sans que l'sizeof
opérateur ne soit évalué.sizeof
, cependant, toujours curieux de savoir s'il existe un moyen intelligent d'y parvenir.)#define masks {0xff, 0xaf, 0x0f}
Si vous utilisez Visual C ++, vous pouvez utiliser
#pragma message
:Edit: Merci à LB pour le lien
Apparemment, l'équivalent GCC est (non testé):
la source
BOOST_PP_STRINGIZE
qui est belle et courte et copiable / collable.Autant que je sache, «#error» n'imprimera que des chaînes, en fait, vous n'avez même pas besoin d'utiliser des guillemets .
Avez-vous essayé d'écrire divers codes intentionnellement incorrects en utilisant "BOOST_VERSION"? Peut-être quelque chose comme "bla [BOOST_VERSION] = foo;" vous dira quelque chose comme "la chaîne littérale 1.2.1 ne peut pas être utilisée comme adresse de tableau". Ce ne sera pas un joli message d'erreur, mais au moins, il vous montrera la valeur pertinente. Vous pouvez jouer jusqu'à ce que vous trouviez une erreur de compilation qui vous indique la valeur.
la source
std::vector<BOOST_VERSION>;
dans gcc 4.4.1. Merci!Sans boost:
redéfinissez la même macro et le compilateur HIMSELF donnera un avertissement.
De l'avertissement, vous pouvez voir l'emplacement de la définition précédente.
vi fichier de définition précédente.
la source
__cplusplus
.Dans Microsoft C / C ++, vous pouvez utiliser la fonction intégrée
_CRT_STRINGIZE()
pour imprimer des constantes. Beaucoup de messtdafx.h
fichiers contiennent une combinaison de ceux-ci:et produit quelque chose comme ceci:
la source
Fonctionne même si
preprocess to file
est activé, même si des jetons non valides sont présents:la source
Build error: #include expects "FILENAME" or <FILENAME>
. Soupir.'
:*** WARNING C318 IN LINE 2 OF test.c: can't open file '::*/`'
Vous pouvez également prétraiter le fichier source et voir ce que la valeur du préprocesseur évalue.
la source
Cherchez-vous
Pas génial si BOOST_VERSION est une chaîne, comme je l'ai supposé, mais il peut aussi y avoir des entiers individuels définis pour les numéros majeur, mineur et de révision.
la source
#if VARIABLE == 123
instruction à la volée et la coloration syntaxique me dit si c'est la valeur que je pense ou non ...Regarder la sortie du préprocesseur est la chose la plus proche de la réponse que vous demandez.
Je sais que vous avez exclu cela (et d'autres moyens), mais je ne sais pas pourquoi. Vous avez un problème assez spécifique à résoudre, mais vous n'avez pas expliqué pourquoi aucune des méthodes "normales" ne fonctionne bien pour vous.
la source
Vous pouvez écrire un programme qui s'imprime
BOOST_VERSION
, le compile et l'exécute dans le cadre de votre système de construction. Sinon, je pense que vous n'avez pas de chance.la source
BOOST_VERSION est défini dans le fichier d'en-tête boost version.hpp.
la source
Jetez également un œil à la documentation Boost, concernant la façon dont vous utilisez la macro:
En référence à
BOOST_VERSION
, à partir de 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 :la source
Au lieu de #error, essayez de redéfinir la macro juste avant qu'elle ne soit utilisée. La compilation échouera et le compilateur fournira la valeur actuelle qu'il pense s'appliquer à la macro.
#define BOOST_VERSION bla
la source