57 votes

Pourquoi utiliser des macros en C?

Double Possible:
Ce sont des C macros utiles pour?

Tous les quelques mois, je reçois une envie d'aller apprendre un peu de C que ma merde collège de la programmation de l'éducation ne jamais couverts. Aujourd'hui, c'est les macros. Ma compréhension de base des macros est qu'ils sont une simple recherche et de remplacement qui se passe sur votre code avant d'être compilé. Je vais avoir du mal à comprendre pourquoi vous devriez utiliser des macros. La plupart des exemples que je suis à la recherche sont quelque chose comme

TEST(a,%d);
#define TEST(a,b) printf(" The value of " #a " = " #b " \n", a)

//which expands to 
printf(" The value of a = %d \n",a);

(exemple ici)

De mon newbie point de vue, il semble que la définition d'une nouvelle fonction serait de vous donner les mêmes résultats. Je peux voir comment, historiquement, les macros serait utile pour la modification d'un lot de la source rapidement dans les jours facile de rechercher et de remplacer, mais quelque chose me dit que je suis pas certains plus gros point.

Alors, quel genre de choses utiles macros peuvent faire pour vous?

76voto

Tyler McHenry Points 35551

Ce n'est pas exactement de recherche et de remplacement, c'est un jeton d'expansion. C macros sont ce que tous les autres types de macro est dans le monde de l'informatique: une façon d'écrire quelque chose de court et simple et automatiquement se transformer en quelque chose de plus long et plus compliqué.

L'une des raisons les macros sont utilisées est la performance. Ils sont un moyen d'éliminer appel de fonction, les frais généraux, car ils sont toujours élargi en ligne, contrairement au mot clé "inline" qui est souvent ignoré indication pour le compilateur, et n'a même pas exister (dans la norme) avant de C99. Voir, par exemple, la FD_ de la famille de macros utilisé en conjonction avec le fd_sets utilisé par sélectionner et pselect. Ces fd_sets sont vraiment juste bitsets, et la FD_ macros sont masquage de bits se tourner les opérations. Il serait ennuyeux d'écrire les bits tourner vous-même tous les temps, et un appel de fonction serait beaucoup de frais généraux pour un fonctionnement rapide si elle n'était pas insérée.

Aussi, les macros peuvent faire certaines choses que les fonctions ne peuvent pas. Envisager de jeton de collage. Depuis le préprocesseur s'exécute avant le compilateur, il peut faire de nouveaux identifiants pour le compilateur à utiliser. Cela peut vous donner un aperçu schématique de créer beaucoup de semblables définitions, par exemple

#define DEF_PAIR_OF(dtype) \
  typedef struct pair_of_##dtype { \
       dtype first; \
       dtype second; \
  } pair_of_##dtype##_t 

 DEF_PAIR_OF(int);
 DEF_PAIR_OF(double);
 DEF_PAIR_OF(MyStruct);
 /* etc */

Une autre chose qu'il peut faire qu'une fonction n'a pas pu tourner au moment de la compilation d'informations dans les informations d'exécution:

#ifdef DEBUG
#define REPORT_PTR_VALUE(v) printf("Pointer %s points to %p\n", #v, v)
#else 
#define REPORT_PTR_VALUE(v)
#endif

void someFunction(const int* reallyCoolPointer) {
  REPORT_PTR_VALUE(reallyCoolPointer);
  /* Other code */
}

Il n'ya aucun moyen qu'une fonction peut utiliser le nom de son paramètre à sa sortie comme la macro. Cela démontre également la compilation sortie de débogage de code pour la release.

50voto

DeusAduro Points 2835

Une des raisons est que, jusqu'à C99, le mot clé inline n'était pas standard dans le langage C. Ainsi, les macros vous ont permis d’intégrer de petites fonctions. D'une certaine manière, ils fonctionnent également comme des modèles, c'est-à-dire. vous n'avez pas besoin de spécifier des types dans la définition de la macro, par exemple:

 #define MAX(x,y) ((x) > (y) ? (x) : (y))
 

Cette macro est compatible avec les entiers, les doubles, les flottants, etc.

18voto

Mike McQuaid Points 4675

Les macros sont développées lors de la compilation. Vous avez raison de dire qu'ils sont souvent maltraités, mais un exemple classique en C serait d'avoir une macro pour écrire des messages de débogage qui (lorsque le mode de débogage est désactivé au moment de la compilation) ne génère pas de code et ne provoque donc aucun ralentissement.

15voto

jeffamaphone Points 31732

Parfois, vous voulez faire de journalisation, mais seulement en mode de débogage. Si vous écrivez quelque chose comme:

#ifdef DEBUG
#define LOG_MSG(x) printf(x);
#else
#define LOG_MSG(X)
#endif

Parfois vous voulez juste changer quelque chose ou désactiver la fonction sur la compilation les temps de commutation. E. g., mon entreprise fait un peu de co-branding de nos produits et de partenaires de poser à son tour des choses. Donc, nous allons faire quelque chose comme:

#ifndef SPECIAL_PARTNER_BUILD
    DoSomethingReallyAwesome();
#endif

Puis construire avec -DSPECIAL_PARTNER_BUILD au moment de donner le partenaire sera en baisse.

Parmi beaucoup d'autres raisons possibles.

Parfois vous voulez juste pour économiser de frappe pour les choses que vous faites maintes et maintes fois. Certaines personnes prennent cela à la mesure (toux MFC toux) et d'écrire ce qui revient à leur propre langue dans les Macros d'abstraction difficile de l'API. Cela rend le débogage d'un frikkin cauchemar.

6voto

lillq Points 4161

Les macros peuvent avoir de nombreuses utilisations différentes de celles de fonctions.

Il est très utile d’utiliser des macros pour tout type de nombre magique ou de chaîne.

 #define MY_MAGIC_NUM 57

/*MY_MAGIC_NUM used all through out the code*/
 

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