38 votes

Que signifie le tilde (~) dans les macros?

Vu sur ce site , le code montre les invocations de macros utilisant un tilde entre parenthèses:

 HAS_COMMA(_TRIGGER_PARENTHESIS_ __VA_ARGS__ (~))
//                                          ^^^
 

Qu'est-ce que cela signifie / fait? Je soupçonne que ce n'est qu'un argument vide, mais je ne suis pas sûr. Est-ce que c'est spécifique à C (99) comme __VA_ARGS__ est spécifique à C99 et existant en C ++?

32voto

Matthieu M. Points 101624

Sur la page d'introduction de Boost.Préprocesseur, un exemple est donné dans A. 4.1.1 Répétition Horizontale

#define TINY_print(z, n, data) data

#define TINY_size(z, n, unused)                                 \
  template <BOOST_PP_ENUM_PARAMS(n, class T)>                   \
  struct tiny_size<                                             \
      BOOST_PP_ENUM_PARAMS(n,T)                                 \
      BOOST_PP_COMMA_IF(n)                                      \
      BOOST_PP_ENUM(                                            \
          BOOST_PP_SUB(TINY_MAX_SIZE,n), TINY_print, none)      \
  >                                                             \
    : mpl::int_<n> {};

BOOST_PP_REPEAT(TINY_MAX_SIZE, TINY_size, ~) // Oh! a tilde!

#undef TINY_size
#undef TINY_print

Une explication est donnée ci-dessous:

Le processus de génération de code est lancé en appelant BOOST_PP_REPEAT, d'un ordre supérieur macro qui à plusieurs reprises appelle la macro nommée par son second argument (TINY_size). Le premier argument spécifie le nombre d'invocations répétées, et la troisième peut être de toutes les données; il est passé sur inchangé à la macro appelée. Dans ce cas, TINY_size n'utilise pas les données, de sorte que le choix de passer ~ est arbitraire. [5]

(l'emphase est mienne)

Et il y a la note:

[5] ~ n'est pas entièrement choix arbitraire. Les deux @ et $ aurait été un bon choix, sauf qu'ils sont pas techniquement partie du jeu de caractères de base de C++ implémentations sont nécessaires pour les soutenir. Un identificateur comme ignoré peut-être l'objet expansion de macro, conduisant à des résultats inattendus.

Le tilde, donc, est tout simplement une place de titulaire parce qu'un argument est requis, mais aucun n'est nécessaire. Depuis n'importe quel utilisateur identifiant défini par le wannabe pourrait être élargie, vous devez utiliser quelque chose d'autre.

Il s'avère qu' ~ est quasiment inutilisés (binaire négation n'est pas souvent que l'appelé) en comparaison à l' + ou - par exemple, il ya donc peu de risque de confusion. Une fois que vous avez réglé sur ce, à l'aide de manière uniforme, et il lui donne un nouveau sens à la tilde; comme l'utilisation d' operator<< et operator>> pour le streaming de données est devenue une C++ idiome.

4voto

aschepler Points 23731

Le ~ ne fait rien. Presque tout autre contenu à l'intérieur de ces parenthèses fonctionnerait de la même manière.

L’essentiel de cette astuce consiste à vérifier si _TRIGGER_PARENTHESIS_ est proche de (~) dans l’expansion de _TRIGGER_PARENTHESIS_ __VA_ARGS__ (~) . Quoi qu'il en soit, HAS_COMMA(...) étend ses arguments à 0 ou 1 .

3voto

Alok Save Points 115848

Les arguments à tester sont placés entre la macro et ses parenthèses, la macro ne se déclenche que si les arguments sont vides:

 _TRIGGER_PARENTHESIS_ __VA_ARGS__ (~)
 

NOTE: En fait, le lien que vous avez posté l'indique. Je vérifierai s'il y a une référence à cela dans la norme.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X