web-dev-qa-db-fra.com

Un utilitaire pour tester l'extension des macros C / C ++ #define?

Il semble que je passe souvent trop de temps à essayer d'obtenir une macro #define pour faire exactement ce que je veux. Je publierai mon dilemme actuel ci-dessous et toute aide est appréciée. Mais vraiment la plus grande question est de savoir s'il existe un utilitaire que quelqu'un pourrait recommander, pour afficher rapidement ce qu'une macro fait réellement? Il semble que même le processus lent d'essais et d'erreurs irait beaucoup plus vite si je pouvais voir ce qui ne va pas.

Actuellement, je charge dynamiquement une longue liste de fonctions à partir d'un DLL que j'ai créé. La façon dont j'ai configuré les choses, les pointeurs de fonction ont les mêmes nanes que les fonctions exportées, et le Les typedef (s) utilisés pour les prototyper ont les mêmes noms, mais avec un trait de soulignement en préfixe. Je souhaite donc utiliser un define pour simplifier les affectations d'une longue liste de pointeurs de fonction.

Par exemple, dans l'instruction de code ci-dessous, "hexdump" est le nom d'un point de fonction typedef'd, et est également le nom de la fonction, tandis que _hexdump est le nom du typedef. Si GetProcAddress () échoue, un compteur d'échec est incrémenté.

if (!(hexdump = (_hexdump)GetProcAddress(h, "hexdump"))) --iFail;

Alors disons que j'aimerais remplacer chaque ligne comme ci-dessus par une macro, comme celle-ci ...

GETADDR_FOR(hexdump )

Eh bien, c'est le meilleur que j'ai trouvé jusqu'à présent. Cela ne fonctionne pas (mon // commentaire est juste pour empêcher le formatage du texte dans le message) ...

// #define GETADDR_FOR(a) if (!(a = (#_#a)GetProcAddress(h, "/""#a"/""))) --iFail; 

Et encore une fois, alors que j'apprécierais un aperçu de l'erreur stupide que j'ai faite, cela ferait de ma journée d'avoir un utilitaire qui me montrerait l'erreur de mes voies, en branchant simplement ma macro.

40
Randy

enter image description here Allez sur https://godbolt.org/ . Entrez votre code dans le volet gauche et sélectionnez le compilateur comme gcc, placez l'argument comme -E dans le volet droit. Votre code prétraité apparaîtra sur la droite.

47
Mohit

Vous pouvez simplement exécuter votre code via le préprocesseur, qui vous montrera dans quoi il sera développé (ou crachera des erreurs si nécessaire):

 $ cat ac 
 # define GETADDR_FOR (a) if (! (a = (# _ # a) GetProcAddress (h, "/" "# a"/""))) 
 GETADDR_FOR (hexdump) 
 
 $ Gcc -E ac 
 # 1 "ac" 
 # 1 "<built-in>" 
 # 1 "<ligne-commande>" 
 # 1 "ac" 
 Ac: 1: 36: erreur: '#' n'est pas suivi d'un paramètre de macro 
 
 GETADDR_FOR (vidage hexadécimal) 

Dans GCC, c'est gcc -E foo.c pour prétraiter uniquement le fichier.

Visual Studio utilise le /P argument.

24
Mark Rushakoff
6
Kester

Vous semblez ne pas savoir quelle est la syntaxe exacte pour la stringification ou le collage de jetons dans les macros de préprocesseur C.

Vous trouverez peut-être cette page sur macros de préprocesseur C en général utile.

En particulier, je pense que cette macro devrait se lire comme ceci:

#define GETADDR_FOR(a) if (!(a = (_##a)GetProcAddress(h, #a))) --iFail

Le ; De fin doit être ignoré car vous allez probablement le taper comme GETADDR_FOR(hexdump);, et si vous ne le faites pas, cela semblera très étrange dans votre code C et confondra beaucoup de surligneurs de syntaxe.

Et comme quelqu'un d'autre l'a mentionné, gcc -E Exécutera le préprocesseur et sautera les autres étapes de compilation. Ceci est utile pour déboguer les problèmes de préprocesseur.

2
Omnifarious

Vous voudrez peut-être jeter un oeil à Boost Wave . Comme la plupart des Boost, c'est vraiment plus une bibliothèque qu'un utilitaire, mais il a un pilote pour agir comme un préprocesseur complet.

1
Jerry Coffin