用于枚举的宏的实用程序

Pas*_*uoq 12 c c-preprocessor

socket.h我的Linux系统上的一个标题如下所示.

/* 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
...
Run Code Online (Sandbox Code Playgroud)

定义一种用于在C创建type-safe-ish常量enum习惯用法,该语言实际上将其视为编译时常量.

我的问题是:宏定义什么目的MSG_OOB,MSG_PEEK...展开自己服务?

Jen*_*edt 7

这些定义的目的是应用程序可以执行类似的操作

#ifdef MSG_OOB
  some code here
#endif
Run Code Online (Sandbox Code Playgroud)

宏的扩展不是递归的,因此宏的评估MSG_OOB结果是同名的enum常量MSG_OOB.

还要将常量声明为有enum帮助,例如在调试时.


Sne*_*tel 6

POSIX标准要求"符号常量",例如MSG_DONTROUTE"类似对象的宏",而不是枚举.将它们定义为自身允许它们在枚举的上下文中使用,以及例如与其一起正常工作#ifdef.

从POSIX标准:

标题应定义以下符号常量.... MSG_DONTROUTE

和:

符号常量...指的是C预处理器符号(也没有参数).

最后,从附录中:

如果一个常量需要是一个宏,但也允许它是另一种类型的常量,例如枚举常量,那么在将它定义为另一种常量的实现上,宏通常定义如下:

#define macro_name macro_name

这允许应用程序的#ifdef使用等来确定该宏是否被定义,但宏不是在#if预处理指令使用,因为预处理器将把未膨胀字MACRO_NAME为具有零值.