web-dev-qa-db-fra.com

Pourquoi la bibliothèque C utilise-t-elle des macros et fonctionne avec le même nom?

Je lis "la bibliothèque C standard C" par PJ Plaudeur, qui est vraiment intéressante. Le livre explique non seulement comment utiliser la bibliothèque, mais également la manière dont elle est mise en œuvre.

J'ai fini de lire le ctype.h Section et dans l'en-tête, les fonctions sont déclarées comme des macros et des fonctions. Par exemple

int isdigit(int);

mais aussi

#define isdigit(c) (_Ctype[(int)(c)] & _DI)

Je ne comprends pas pourquoi les deux sont utilisés?

De plus, si j'essaie de recréer ma propre coutume ctype-en-tête et ma mise en œuvre, je ne peux compiler que avec succès si je supprimais la macro (commentaire de la définition).

Cet aspect n'a pas été vraiment expliqué dans le livre. Quelqu'un peut-il s'il vous plaît expliquer?

20
user619818

La macro est (putablement) plus efficace, car elle n'implique pas d'appel de fonctions. Il peut être optimisé plus facilement, car il s'agit simplement d'une recherche offset du pointeur.

L'appel de la fonction permet de créer une liaison avec la même bibliothèque, même si le programme a été compilé sans la définition macro-macro - s'il était compilé avec un en-tête différent ou juste avec une déclaration de voyous dans le fichier source. Devrait, par exemple, vous avez un compilateur qui a une "amélioration" de quelqu'un de ctype.h que non Avoir la macro, la fonction existerait toujours au moment de l'utilisation.

Si nous regardons la norme:

C99

7.1.4 Utilisation des fonctions de la bibliothèque

Toute fonction déclarée dans une en-tête peut être en outre mise en oeuvre en tant que macro-définie en forme de fonction dans l'en-tête. Si une fonction de bibliothèque est déclarée explicitement lorsque son en-tête est inclus, l'une des techniques présentées ci-dessous peut être utilisée pour assurer la déclaration de la déclaration. affecté par une telle macro. Toute macro définition d'une fonction peut être supprimée localement en joignant le nom de la fonction entre parenthèses, car le nom n'est alors pas suivi de la parenthèse gauche qui indique une expansion d'un nom de la fonction macro. Pour la même raison syntaxique, il est permis de prendre l'adresse d'une fonction de bibliothèque même si elle est également définie comme une macro.

Cela signifie que si vous écrivez:

int b = (isdigit)(c);

ou

int (*f)(int) = &isdigit;
int b = f(c);

ensuite, vous appelez la fonction réelle, pas la macro. Vous pouvez également écrire légalement:

#undef isdigit
int b = isdigit(c);

ou (dans un fichier source n'ayant pas #include <ctype.h> directement ou transitoire):

extern int isdigit(int);
int b = isdigit(c);
23
ecatmur