Quels sont les trucs que je peux utiliser avec des macros?
Dans notre code de legs, ainsi que de la modernisation de notre code, nous utilisons des macros pour effectuer des solutions astucieuses comme le code des générations, etc. Et nous utilisons à la fois la #
et ##
opérateurs.
Je suis curieux de voir comment les autres développeurs à utiliser des macros pour faire des choses aussi cool, si on les utilise à tous.
- Je n'aime pas les macros. Ils ne font pas partie de la langue.
- C'est trop mauvais... ils font, en fait, introduire les questions si pas utilisé à bon escient. Néanmoins, ils résolvent beaucoup de problèmes...
- La chose que je déteste à propos des macros, c'est qu'ils sont souvent écrits entièrement en majuscules, rendre le code moche et bruyant.
- richb est une macro
- "Macro" se réfère à tout ce définies à l'aide de "#define", mais j'ai l'impression que vous parlez de la fonction-comme les macros en particulier (par opposition à l'objet-comme les macros). Pourrait-il la peine de l'édition du titre de l'indiquer?
Vous devez vous connecter pour publier un commentaire.
En C, il est courant de définir des macros que faire des trucs d'obtenir le verbatim argument, et en même temps de définir des fonctions pour être en mesure d'obtenir l'adresse d'une manière transparente.
boost::math::isnan(z);
ne compile pas mais(boost::math::isnan)(z);
sera ... dommage, j'ai dû plonger dans vos commentaires. J'aurais du me douter que C++ guru comme vous devriez avoir répondu 🙂 je suis fan 😉 Cheers !Plus cool de la macro est: affirmer, comprenant des protections, __FILE__, __LINE__.
Évitez d'utiliser d'autres macro dans votre code.
EDIT:
L'utilisation de macros que lorsque vous n'avez pas de solution juridique w/o eux.
Il y a aussi le X Macro langage qui peut être utile pour les peaux SÈCHES et simple de génération de code :
On définit dans un en-tête gen.x une sorte de table à l'aide d'un pas encore défini macro :
Alors il peut l'utiliser dans des endroits différents de la définition pour chaque #include avec une définition différente :
#undef GENX
à l'intérieur de gen.x?Vous pouvez avoir un coup d'oeil à Coup de pouce.Préprocesseur de trouver beaucoup de choses intéressantes sur les usages du préprocesseur...
SHOW() pour le débogage:
La double évaluation pour développer les arguments truc: (E. g. Utilisez le numéro de la ligne et non pas "_LIGNE___".)
Statique au moment de la compilation des assertions.
E. g.:
Utilisé avec:
De l'initialisation d'une instance de la classe CodeLocation: (Stockage de Fichiers/Ligne/de Fonction à partir du point d'invocation, cela peut UNIQUEMENT être fait avec une macro ou en accédant directement à l' __FICHIER__/__LIGNE__/etc macros au point source.)
Par la suite utilisé par MESSAGE/ALERTER/ÉCHEC des macros comme une source pratique-emplacement du mécanisme d'impression. Par exemple:
Affirmer Que les macros. Vous pouvez passer n'importe quel jeton, y compris les opérateurs comme le '==', grâce à une macro. Si des expressions comme:
Ou
Sont légales. Affirmer Que les macros peuvent ajouter automatiquement toutes sortes de nice infos utiles comme CodeLocation, les traces de pile, ou de lever des exceptions /coredumping /sortie gracieusement.
Faire errno de plus simple:
E. g. printf( "échec de l'ouverture. "ERRNO_FORMAT, ERRNO_ARGS );
Un de mes trucs favoris est un moyen de passer un nombre variable d'arguments à des macros, pour être utilisé plus tard dans l'appel de printf comme des fonctions par exemple. Pour ce faire, je précise que la macro n'a qu'un seul paramètre et l'utiliser dans le corps de la macro sans (), mais passer tous les paramètres de la macro (( et )), de sorte que la liste ressemble à un seul argument. Par exemple,
La journalisation est un endroit où les macros sont particulièrement souvent utilisé:
J'crédit Sean Barrett pour ce plaisir un:
Un hacky façon à obtenir le préprocesseur pour générer du code pour vous sur la base d'un niveau supérieur de la structure que vous pouvez exprimer au travers de macros.
La place j'utilise des macros est dans mon propre framework de test. Par exemple, quand je veux affirmer que certains de code doit lancer, j'utilise cette macro:
Et de l'utiliser comme ceci:
Le seul autre endroit où je les utiliser dans les déclarations de classe. J'ai une macro:
que j'utilise pour indiquer qu'une classe ne peut pas être copié (ou affecté):
ce n'est pas faire quelque chose de spécial, mais attire l'attention des peuples et peuvent facilement être utilisés pour la recherche.
De code embarqué, un joli tour de embeddedgurus.com
vous permet de gérer des valeurs binaires:
Ce atteindre les mêmes objectifs que la précédente réponse de @Ferruccio sur BOOST_BINARY, bien qu'un peu élargi.
Voici le code (copie n collé, non testé, voir le lien pour plus de détails)
J'aime les macros. Donc, beaucoup de plaisir lors du débogage de !
J'ai souvent envelopper les choses comme debug sonar dans une macro simple qui lui permet d'être compilé de release:
Utilisation ultérieure est généralement quelque chose comme:
La
do{}while(0)
idiome est là pour éviter les problèmes qui pourraient résulter de faire accidentellement utilisation deD(...)
le seul contenu d'un sursis ou d'une boucle. Vous ne voulez pas de code de ce genre pour dire la mauvaise chose, après tout:Si je pouvais faire ce cas jeter une erreur, je le ferais, mais le préprocesseur aurait un compilateur lui-même à dire que le
D()
macro a été le seul contenu d'un corps de boucle.Je suis aussi un grand fan de la compilation des assertions. Ma formulation est légèrement différente, mais n'a pas de réels avantages par rapport aux autres que j'ai vu. La clé est de former un nom unique définition de type qui renvoie une erreur si on a affirmé que la condition est fausse, et pas autrement. Dans cassert.h nous avons:
Et, dans certains fichier source, n'importe où, un typedef serait légal:
L'résultant message d'erreur est souvent obscur, mais contiendra le fragment de l'identificateur de l'activation de la ligne fautive d'être découvert par la force brute.
J'ai été coupable de l'utilisation du préprocesseur dans des endroits où la rédaction d'un code de génération de l'utilitaire de ce qui aurait été le préféré de réponse, un peu comme le code dans une autre réponse qui a généré beaucoup de chaudière-plaque de base sur les pièces uniques d'une enum nom du membre. Qui est particulièrement utile lors de l'écriture d'un grand nombre de messages-envoi de la colle à être compilée en c
Struct littéraux avec des valeurs par défaut (qui ne sont pas à zéro), à l'aide de C99 variadic macros
à l'aide de
EXAMPLE(.name="test")
utilise les valeurs par défaut, sauf pour l'explicite remplacement dename
. Cette répétition plus tard, les mentions de la même membre est bien définie dans la norme.On peut simplifier des choses répétitives pour ie. enum listes
...et plus tard faire un interrupteur cours d'une manière structurée
Remarque: Sûr que cela pourrait être fait avec un tableau de pointeur de fonction, mais cela ouvre pour un peu plus de souplesse pour ajouter des paramètres et également utiliser la chaîne d'extensions de hachage unique.
...ou de test sur les cordes pour obtenir la bonne valeur d'enum
Vous pouvez utiliser des macros pour définir la même fonctionnalité avec différents types de données. Par exemple:
Dans cet exemple définit trois fonctions (
bits_str_uchar()
,bits_str_uint()
,bits_str_int()
) qui gèrent les trois différents types de données (unsigned char
,unsigned int
,int
). Cependant, tous retourner une chaîne de caractères qui contient les bits de la valeur passée.Lors de l'implémentation d'un serveur COM, vous devez prendre soin de toutes les exceptions de votre code pourrait lancer en laissant une exception par méthode COM limite souvent le plantage de l'application appelante.
Méthodes parenthèses sont utiles pour cela. Il y a une parenthèse ouvrante qui est une macro contenant "essayer" et une parenthèse fermante qui contient un ensemble de "catch"es, l'emballage des exceptions dans ErrorInfo et la production de Hresult.
De la CrashRpt projet , besoin d'astuce pour élargir les macros et les définit:
La plupart (tous?) C++ Tests Unitaires cadres sont construits sur des macros. Nous utilisons UnitTest++. Check it out pour voir toutes sortes de fantaisie macros.
La BOOST_BINARY macro effectue certains clevel pré-processeur de la ruse pour donner le C++, la capacité à exprimer les constantes numériques en binaire. Elle est limitée à 0-255 cependant.
La pthreads utilité des macros sont particulièrement impressionnante à mon humble avis.
Quand je travaille sur de gros c/c++ structures imbriquées comme celui utilisé pour 3GPP CRR/NBAP/RNSAP, j'ai suivi ce truc pour faire du code propre.
Cela va rendre la vie plus facile pendant les temps de maintenance..aussi dans les temps de conception et de code doit être lisible.
De les convertir à une construction de la langue afin d'améliorer la sécurité du type et de la capacité de débogage.
Sur micro-contrôleurs, il est commun pour déboguer le code à l'aide de l'UART, comme le matériel, les points d'arrêt ont de nombreux inconvénients.
C'est une simple macro qui s'est révélée très utile:
Exemple d'utilisation:
Reçu stream:
Oui, c'est brut et dangereux. C'est seulement appliqué jusqu'à ce que le bug est isolé, de sorte que cette macro ne fait pas de mal.
Souvent je l'utilise. J'ai un
debug.h
en-tête définit comme suit:et puis:
si vous souhaitez obtenir
"message from debug!"
message, compiler avec:Sinon, rien ne se passe. Gcc est très intelligent de compilateur. Si
DEBUG
n'est pas défini, à la génération deif(0)
(code mort) seront supprimés à partir de votre code avec quelques optimisations sur.Que vous pouvez faire encore plus:
Il y a quelques jours j'ai vu le D langage de programmation fournir une fonctionnalité très similaire aussi.
Si vous pensez que le ci-dessus sans contexte, vous pouvez définir pense que
Et puis
Dans les macros, il est très facile de faire de flux de contrôle parce que c'est juste le texte de substitution. Voici un exemple avec une boucle for: