在C中说“#define FOO FOO”有什么意义?

我遇到了一些C代码,其中作者在整个地方使用以下习语:

typedef __int32 FOO_INT32; #define FOO_INT32 FOO_INT32 

这样做有什么意义? typedef不应该足够吗? 对于那些有些不稳定的C编译器来说,这是一种解决方法吗?

使用#define指令,您将能够使用以下代码测试typedef是否已在代码中的其他位置完成:

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

这种做法有时候会在标题中完成。 #define允许对typedef的存在进行编译时测试。 这允许代码如下:

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

或者作为真正的守卫#define,类似于头文件守卫。

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

它不一定是一个好的做法,但它有其用途,特别是当你有一些使用其他库定义的类型的标题时,但是当你根本不使用那些库时,你想提供自己的替代案例。

此模式对于微处理器中寄存器的特征检测也很有用,如本问题所示 。 例如,可能有两个类似的头文件,其中一个定义了一个定时器,另一个定义了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; 

这意味着在主代码中,当您包含委托给目标的相应标头的通用processor.h ,您可以检测到function:

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

另一个原因是标准可能要求定义为宏。

来自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 

这里枚举符号也按照相关POSIX规范的要求导出为宏,引用:

标头应定义以下宏,以用作getsockopt()和setsockopt()的level参数的值:

IPPROTO_IP

 Internet protocol. 

IPPROTO_IPV6

 Internet Protocol Version 6.