C 枚举宏的实用程序
在我的Linux系统上,一个headerC 枚举宏的实用程序,c,c-preprocessor,C,C Preprocessor,在我的Linux系统上,一个headersocket.h如下所示 /* Bits in the FLAGS argument to `send', `recv', et al. */ enum { MSG_OOB = 0x01, /* Process out-of-band data. */ #define MSG_OOB MSG_OOB MSG_PEEK = 0x02, /* Peek at incoming
socket.h
如下所示
/* Bits in the FLAGS argument to `send', `recv', et al. */
enum
{
MSG_OOB = 0x01, /* Process out-of-band data. */
#define MSG_OOB MSG_OOB
MSG_PEEK = 0x02, /* Peek at incoming messages. */
#define MSG_PEEK MSG_PEEK
MSG_DONTROUTE = 0x04, /* Don't use local routing. */
#define MSG_DONTROUTE MSG_DONTROUTE
...
定义enum
是一种语言实际视为编译时常量的方法
我的问题是:宏
MSG_OOB
,MSG_PEEK
,…扩展到自身的定义有什么用途?POSIX标准要求像MSG_DONTROUTE
这样的“符号常量”是“类似对象的宏”,而不是枚举器。将它们定义为自己可以在枚举的上下文中使用它们,并且可以正常使用,例如,#ifdef
根据POSIX标准:
标题应定义以下符号常量
....
味精
以及:
符号常数。。。指C预处理器符号(也不带参数)
最后,在附录中:
如果常量必须是宏,但也允许是另一种类型的常量,如枚举常量,则在将其定义为另一种类型的常量的实现中,宏的定义通常如下所示:
#定义宏名称宏名称
这允许应用程序使用#ifdef等来确定宏是否已定义,但该宏在#if预处理器指令中不可用,因为预处理器会将未展开的单词macro_名称视为值为零
这些定义的目的是应用程序可以执行以下操作
#ifdef MSG_OOB
some code here
#endif
宏的扩展不是递归的,因此对宏MSG_OOB
的求值会产生同名的enum
常量MSG_OOB
例如,在调试时,将常量声明为
enum
也会有所帮助。我从未见过它,但我想它会覆盖任何可能的替代定义,因此您可以确定它只是enum。MSG_OOB
扩展到MSG_OOB
@GIJoe您可能在这里找到了一些东西。它们不会扩展到预处理器可以使用的值,但如果有人需要编写,则#ifdef MSG_PEEK
将按预期工作。我将接受你的答案,而不是Jens Gustedt的答案,因为它引用了POSIX。关键在于最后一句话。实际上,这个答案是错误的。请看@Sneftel的答案。@GIJoe这个答案是不完整的,但它补充了Sneftel的优点。@GIJoe,为什么会错呢?问题的目的在于此,而不是关于定义的来源。“这允许应用程序使用#ifdef等来确定宏是否已定义,但该宏在#if预处理器指令中不可用,因为预处理器会将未展开的单词macro_名称视为值为零。”@这句话与这个答案并不矛盾。在#if
指令中预处理器对宏的解释与代码中其他地方(扩展到枚举值)的解释之间存在差异。