我遇到了一些C代码,作者在很多地方都使用以下习惯用法:
typedef __int32 FOO_INT32;
#define FOO_INT32 FOO_INT32
这样做的意义是什么?typedef 不应该足够吗?这是一些奇怪的 C 编译器的解决方法吗?
我遇到了一些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
这并不是一个好的做法,但它有其用途,特别是当您有一些使用其他库定义类型的标题时,但在您根本不使用这些库的情况下,您希望提供自己的替代方案。
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规范要求导出为宏,如引用所示:
The header shall define the following macros for use as values of the level argument of getsockopt() and setsockopt():
IPPROTO_IP
Internet protocol.
IPPROTO_IPV6
Internet Protocol Version 6.
...
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
文件并委托给目标适当的头文件时,您可以检测功能:#include <processor.h>
#ifdef TMR2
x = TMR2;
#else
x = 0; // no timer, probably because we're on the cheaper model
#endif