Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 枚举宏的实用程序_C_C Preprocessor - Fatal编程技术网

C 枚举宏的实用程序

C 枚举宏的实用程序,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

在我的Linux系统上,一个header
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
指令中预处理器对宏的解释与代码中其他地方(扩展到枚举值)的解释之间存在差异。