70 votes

Création macro C avec ## et __LINE__ (jeton concaténation avec positionnement macro)

Je veux créer un C macro qui crée une fonction avec un nom de fonction sur le numéro de ligne. Je pensais que je pouvais faire quelque chose comme (la fonction réelle aurait états à l'intérieur des accolades):

#define UNIQUE static void Unique_##__LINE__(void) {}

Qui je l'espère étendre à quelque chose comme:

static void Unique_23(void) {}

Cela ne fonctionne pas. Avec jeton de concaténation, le positionnement des macros sont traités littéralement, se terminant en expansion:

static void Unique___LINE__(void) {}

Est-ce possible de le faire?

(Oui, il y a une vraie raison pour laquelle je veux faire cela n'importe comment, cela semble inutile).

118voto

Adam Rosenfield Points 176408

Le problème est que lorsque vous avez une macro de remplacement, le préprocesseur ne fera qu'élargir les macros de manière récursive si ni le stringizing opérateur # ni le jeton-coller de l'opérateur ## y sont appliquées. Donc, vous avez à utiliser des couches supplémentaires d'indirection, vous pouvez utiliser le jeton-coller de l'opérateur avec une étendue de manière récursive argument:

#define TOKENPASTE(x, y) x ## y
#define TOKENPASTE2(x, y) TOKENPASTE(x, y)
#define UNIQUE static void TOKENPASTE2(Unique_, __LINE__)(void) {}

Ensuite, __LINE__ obtient élargi pour le numéro de la ligne lors de l'expansion de l' UNIQUE (puisqu'il n'est pas impliqué avec soit # ou ##), puis le jeton en collant qui se passe lors de l'expansion de l' TOKENPASTE.

Il convient également de noter qu'il existe aussi l' __COUNTER__ macro, qui s'étend à un nouveau entier à chaque fois qu'il est évalué, dans le cas où vous avez besoin d'avoir plusieurs instanciations de l' UNIQUE macro sur la même ligne. Remarque: __COUNTER__ est pris en charge par MS Visual Studio et GCC (depuis la V4.3), mais n'est pas standard C.

5voto

Ben Stiglitz Points 3054
<p>Je pense que vous pouvez obtenir ce travail avec <a href="http://en.wikipedia.org/wiki/C%5Fpreprocessor#Indirectly%5Fquoting%5Fmacro%5Farguments" rel="nofollow">expansion macro indirecte</a>.</p>

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: