4 votes

Comment générer un nom de fonction en utilisant une macro C

La macro "VER" est définie comme "((u_long)1)" dans un autre fichier d'en-tête que je ne peux pas modifier.

Dans mon code, j'ai besoin de composer la fonction "test_1" en utilisant "test" et VER. Cependant, le compilateur a signalé une erreur car il a généré "test_((u_long)1)" au lieu de "test_1".

Ma question est : Comment écrire une macro pour qu'elle puisse générer "test_1" ?

Merci d'avance !

#define VER ((u_long)1)      /* Ceci est défini dans un autre fichier d'en-tête que je ne peux pas modifier */

#define paste(x, y, z) x ## y ## z
#define paste2(x, y, z) paste(x, y, z)
#define fcall(fname) paste2(fname, _, VER)

int test_1() {
  return 0;
}

int main() {
  fcall( test )();
  return 0;
}

6voto

Angew Points 53063

Je ne peux pas garantir que c'est 100% portable, mais ça devrait fonctionner :

#define VER ((u_long)1)

#define STRIP1(x) STRIP2 x

#define STRIP2(x) STRIP3 x

#define STRIP3(x)

#define paste(x, y, z) x ## y ## z
#define paste2(x, y, z) paste(x, y, z)
#define fcall(fname) paste2(fname, _, STRIP1(VER))

Exemple en direct

Cela fonctionne en interprétant les parenthèses à l'intérieur de la définition de VER comme une invocation de macro. Voici les expansions individuelles, telles qu'elles se produisent :

STRIP1(VER) // STRIP1 avec l'argument VER

STRIP2 ((u_long)1) // STRIP2 avec l'argument (u_long)1

STRIP3 (u_long)1  // STRIP3 avec l'argument u_long, suivi de 1

1

Si nous réarrangeons les espaces (ils sont insignifiants de toute façon), nous obtenons ceci :

STRIP1(VER)

STRIP2((u_long) 1)

STRIP3(u_long) 1

1

0voto

Mats Petersson Points 70074

Avec cette source, vous ne pourrez probablement pas le faire, car l'expansion de macros est textuelle, donc le ((u_long)1) ne peut pas devenir 1.

Une solution serait bien sûr d'écrire du code pour afficher la valeur réelle de VER. L'autre alternative est de convaincre les personnes propriétaires du fichier que vous ne pouvez pas le modifier et qu'ils devraient le faire pour vous...

0voto

BLUEPIXY Points 18514

Comme version modifiée d'Angew

#define VER ((u_long)1)

#define _(x) x
#define id(x) _(x)

#define STRIP3(x)
#define STRIP2(x) id(STRIP3 x)
#define STRIP1(x) id(STRIP2 x)

#define paste(x, y, z) x ## y ## z
#define paste2(x, y, z) paste(x, y, z)
#define fcall(fname) paste2(fname, _, STRIP1(VER))

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