Pourquoi certaines routines de bibliothèque sont-elles implémentées simultanément sous forme de macros? Pourquoi la macro “va_arg” est-elle déclarée en tant que fonction (sans “#define”)?

Je me bats pour le dire clairement. Alors laissez-moi le mettre en morceaux. Les contextes sont tirés du livre C de Mike Banahan (liens fournis avec chaque partie ci-dessous). Voici mes questions sous forme de points en gras:

  • Pourquoi certaines fonctions de la bibliothèque sont-elles implémentées simultanément en tant que macros? Quel est le besoin? Voici ce que j’ai lu dans le livre (section 9.1.1) :

Un dernier point général est que beaucoup de routines de bibliothèque peuvent être implémentées sous forme de macros, à condition qu’il n’y ait aucun problème d’effets secondaires (comme décrit au chapitre 7). La norme garantit que, si une fonction est normalement implémentée en tant que macro, une véritable fonction sera également fournie pour effectuer le même travail. Pour utiliser la fonction réelle, définissez soit le nom de la macro avec #undef , soit insérez-le entre parenthèses, ce qui garantit qu’elle ne sera pas traitée comme une macro:

  • va_start , comme nous le soaps, est une fonction ou une macro? Le texte suivant du livre est source de confusion car il implique les deux dans le même souffle, dans les lignes adjacentes !! (Section 9.9)

Avant toute tentative d’access à une liste d’arguments variables, il faut appeler va_start . Il est défini comme

#include  void va_start(va_list ap, parmN); 

La macro va_start initialise ap pour une utilisation ultérieure par les fonctions va_arg et va_end .

  • Et enfin, la partie la plus déroutante. Dans la ligne suivante, il est clairement écrit que va_arg est une macro et continue en montrant son implémentation. Mais comment une macro peut-elle être implémentée sans un mot clé #define , et cela aussi avec un type de retour (‘type’) comme si elle était une fonction? (Section 9.9)

Une fois initialisés, les arguments fournis sont accessibles séquentiellement au moyen de la macro va_arg . Cela est particulier car le type renvoyé est déterminé par un argument de la macro. Notez que cela est impossible à implémenter en tant que vraie fonction, mais en tant que macro. Il est défini comme

 #include  type va_arg(va_list ap, type); 

Vos réponses seront très appréciées. Je vous remercie.

    Ce sont deux questions distinctes.

    Premièrement, va_start , va_arg et va_end sont des macros. va_arg ne peut pas être une fonction, car son deuxième argument est un type plutôt qu’une valeur.

    En ce qui concerne la raison pour laquelle certaines fonctions sont également des macros: vous souhaitez un appel en ligne, ce qui le rend rapide, mais vous pouvez également choisir son adresse et la placer dans un pointeur de fonction:

     int (*function_pointer)(int, FILE *) = &(putc);