Quel est l’intérêt de dire «#define FOO FOO» en C?

Je suis tombé sur un code C où l’auteur utilise partout l’idiome suivant:

typedef __int32 FOO_INT32; #define FOO_INT32 FOO_INT32 

Quel est le sharepoint faire cela? Le typedef ne devrait-il pas suffire? C’est une solution de contournement pour certains compilateurs C saturés?

Avec l’instruction #define , vous pourrez alors vérifier si le typedef a été effectué ailleurs dans le code en utilisant:

 #ifdef FOO_INT32 FOO_INT32 myfoo; #else int myfoo; #endif 

C’est une pratique qui est parfois faite dans les en-têtes. #Define permet de tester l’existence du typedef lors de la compilation. Cela permet un code comme:

 #ifdef FOO_INT32 FOO_INT32 myfoo; #else int myfoo; #endif 

ou en tant que véritable garde #define, semblable aux gardes de fichiers d’en-tête.

 #ifndef FOO_INT32 typedef int FOO_INT32 #define FOO_INT32 FOO_INT32 #endif 

Ce n’est pas nécessairement une bonne pratique, mais cela a des utilisations, en particulier lorsque vous avez des en-têtes qui utilisent des types définis par d’autres bibliothèques, mais que vous souhaitez fournir vos propres substituts pour les cas où vous n’utilisez pas ces bibliothèques.

Ce modèle est également utile pour la détection de caractéristiques des registres dans les microprocesseurs, comme dans cette question . Par exemple, il peut y avoir deux fichiers d’en-tête similaires, l’un définissant un minuteur et l’autre 2:

cheapprocessor.h :

 #define TMR1 TMR1 extern volatile int TMR1; 

expensiveprocessor.h :

 #define TMR1 TMR1 extern volatile int TMR1; #define TMR2 TMR2 extern volatile int TMR2; 

Ce qui signifie dans votre code principal, lorsque vous incluez un processor.h générique.h qui délègue à l’en-tête approprié pour la cible, vous pouvez détecter les fonctionnalités suivantes:

 #include  #ifdef TMR2 x = TMR2; #else x = 0; // no timer, probably because we're on the cheaper model #endif 

Une autre raison est qu’une norme peut nécessiter que les définitions soient des macros.

Extrait de glibc netinet/in.h :

 /* Standard well-defined IP protocols. */ enum { IPPROTO_IP = 0, /* Dummy protocol for TCP. */ #define IPPROTO_IP IPPROTO_IP IPPROTO_ICMP = 1, /* Internet Control Message Protocol. */ #define IPPROTO_ICMP IPPROTO_ICMP IPPROTO_IGMP = 2, /* Internet Group Management Protocol. */ #define IPPROTO_IGMP IPPROTO_IGMP 

Ici, les symboles d’énumération sont également exportés sous forme de macros comme requirejs par la spécification POSIX pertinente , en citant:

L’en-tête doit définir les macros suivantes à utiliser comme valeurs de l’argument de niveau de getsockopt () et de setsockopt ():

IPPROTO_IP

 Internet protocol. 

IPPROTO_IPV6

 Internet Protocol Version 6.