“#define X X”是啥意思?

Posted

技术标签:

【中文标题】“#define X X”是啥意思?【英文标题】:What does it mean by "#define X X"?“#define X X”是什么意思? 【发布时间】:2020-10-02 22:15:22 【问题描述】:

在Linux头文件epoll.h中,我找到了如下代码:

enum EPOLL_EVENTS

    EPOLLIN = 0x001,
#define EPOLLIN EPOLLIN
...

#define EPOLLIN EPOLLIN 是什么意思?

【问题讨论】:

可能是处理有#ifdef EPOLLIN的代码来检查是否定义了。 可能是用在像#if EPOLLIN这样的句子中。如果您将其保留为#define EPOLLIN,则只能与#ifdef一起使用 限于您的标题,glibc's stdio.h 也对stdoutstdinstderr 使用了类似的技巧,但目的不同:让标准满意。 我的猜测是,最初只有 #define EPOLLIN 0x001 等在它们被放入 enum 之前,这保留了依赖于定义的代码的向后兼容性。 @Berge 是的,就是这样。在其他 C 库中,这些宏直接扩展为数字常量。 Glibc 想要使用枚举来设置值,因为这使调试器可以使用符号名称,但 ISO C 要求它们是预处理器宏,所以这是一种两种方式都有的技巧。 【参考方案1】:

这将创建一个名为 EPOLLIN 的宏,其替换文本也是 EPOLLIN

这很可能是预处理器检查哪些事件代码可用并根据需要有条件地编译代码的一种方式。如果我们访问 glibc 的 git repo 并查看 git blame 的输出,我们会看到 enum EPOLL_EVENTS 的以下内容:

ad3bf20c (Ulrich Drepper 2002-12-16 23:38:42 +0000  34) enum EPOLL_EVENTS
ad3bf20c (Ulrich Drepper 2002-12-16 23:38:42 +0000  35)    
ad3bf20c (Ulrich Drepper 2002-12-16 23:38:42 +0000  36)     EPOLLIN = 0x001,
ad3bf20c (Ulrich Drepper 2002-12-16 23:38:42 +0000  37) #define EPOLLIN EPOLLIN
ad3bf20c (Ulrich Drepper 2002-12-16 23:38:42 +0000  38)     EPOLLPRI = 0x002,
ad3bf20c (Ulrich Drepper 2002-12-16 23:38:42 +0000  39) #define EPOLLPRI EPOLLPRI
ad3bf20c (Ulrich Drepper 2002-12-16 23:38:42 +0000  40)     EPOLLOUT = 0x004,
ad3bf20c (Ulrich Drepper 2002-12-16 23:38:42 +0000  41) #define EPOLLOUT EPOLLOUT
ad3bf20c (Ulrich Drepper 2002-12-16 23:38:42 +0000  42)     EPOLLRDNORM = 0x040,
ad3bf20c (Ulrich Drepper 2002-12-16 23:38:42 +0000  43) #define EPOLLRDNORM EPOLLRDNORM
ad3bf20c (Ulrich Drepper 2002-12-16 23:38:42 +0000  44)     EPOLLRDBAND = 0x080,
ad3bf20c (Ulrich Drepper 2002-12-16 23:38:42 +0000  45) #define EPOLLRDBAND EPOLLRDBAND
ad3bf20c (Ulrich Drepper 2002-12-16 23:38:42 +0000  46)     EPOLLWRNORM = 0x100,
ad3bf20c (Ulrich Drepper 2002-12-16 23:38:42 +0000  47) #define EPOLLWRNORM EPOLLWRNORM
ad3bf20c (Ulrich Drepper 2002-12-16 23:38:42 +0000  48)     EPOLLWRBAND = 0x200,
ad3bf20c (Ulrich Drepper 2002-12-16 23:38:42 +0000  49) #define EPOLLWRBAND EPOLLWRBAND
ad3bf20c (Ulrich Drepper 2002-12-16 23:38:42 +0000  50)     EPOLLMSG = 0x400,
ad3bf20c (Ulrich Drepper 2002-12-16 23:38:42 +0000  51) #define EPOLLMSG EPOLLMSG
ad3bf20c (Ulrich Drepper 2002-12-16 23:38:42 +0000  52)     EPOLLERR = 0x008,
ad3bf20c (Ulrich Drepper 2002-12-16 23:38:42 +0000  53) #define EPOLLERR EPOLLERR
5e826ab5 (Ulrich Drepper 2003-03-25 01:14:36 +0000  54)     EPOLLHUP = 0x010,
ad3bf20c (Ulrich Drepper 2002-12-16 23:38:42 +0000  55) #define EPOLLHUP EPOLLHUP
94833f11 (Ulrich Drepper 2007-10-28 01:34:10 +0000  56)     EPOLLRDHUP = 0x2000,
94833f11 (Ulrich Drepper 2007-10-28 01:34:10 +0000  57) #define EPOLLRDHUP EPOLLRDHUP
981569c7 (Joseph Myers   2016-03-14 19:04:53 +0000  58)     EPOLLEXCLUSIVE = 1u << 28,
981569c7 (Joseph Myers   2016-03-14 19:04:53 +0000  59) #define EPOLLEXCLUSIVE EPOLLEXCLUSIVE
f8d44fdc (Andreas Jaeger 2012-07-26 13:11:33 +0200  60)     EPOLLWAKEUP = 1u << 29,
f8d44fdc (Andreas Jaeger 2012-07-26 13:11:33 +0200  61) #define EPOLLWAKEUP EPOLLWAKEUP
4920765e (Ulrich Drepper 2011-12-21 22:14:05 -0500  62)     EPOLLONESHOT = 1u << 30,
e11676dd (Ulrich Drepper 2004-01-21 06:23:26 +0000  63) #define EPOLLONESHOT EPOLLONESHOT
4920765e (Ulrich Drepper 2011-12-21 22:14:05 -0500  64)     EPOLLET = 1u << 31
5e826ab5 (Ulrich Drepper 2003-03-25 01:14:36 +0000  65) #define EPOLLET EPOLLET
ad3bf20c (Ulrich Drepper 2002-12-16 23:38:42 +0000  66)   ;

从这里,您可以看到这些事件中的大多数是在 2002 年创建的,但还有一些是后来添加的。因此,这些宏允许您检查特定标志是否可用,如下所示:

#ifdef EPOLLEXCLUSIVE 
/* code that can handle EPOLLEXCLUSIVE */
#else
/* code that uses an alternate event */
#endif

这样,代码可以在具有可用新事件的较新 Linux 版本上运行,也可以在没有可用事件的旧版本上运行。

【讨论】:

为此,#define EPOLLIN 还不够吗? @DYZ 如果你这样做,那么枚举将不会编译,因为预处理器会将EPOLLIN 枚举成员替换为空白字符串。 @dbush DYZ 我认为 DYZ 的建议是他们做#ifdef EPOLLIN_SUPPORTED 然后使用EPOLLIN 而不是用同名符号定义一个宏【参考方案2】:

#define EPOLLIN EPOLLIN

这将预处理器宏EPOLLIN 定义为EPOLLIN

它可能是为了以后的#ifdef EPOLLIN 检查而定义的。

【讨论】:

以上是关于“#define X X”是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章

“?”是啥意思?在 Erlang 中是啥意思? [复制]

“this”这个词是啥意思,“static”是啥意思?

“||”是啥意思在 var 语句中是啥意思? [复制]

CVE是啥意思,CVE是啥意思

“内容”是啥意思:在招摇/openapi“响应”中是啥意思:

TypeScript 这个语法“-?”是啥意思? (破折号问题)是啥意思?