【问题标题】:Why use both anonymous enum and define macros for constants? [duplicate]为什么同时使用匿名枚举和为常量定义宏?
【发布时间】:2016-02-10 01:54:02
【问题描述】:

为什么 netinet/in.h 以这种方式定义常量?

enum
{
    IPPROTO_IP = 0,    
#define IPPROTO_IP          IPPROTO_IP
    IPPROTO_HOPOPTS = 0,   
#define IPPROTO_HOPOPTS     IPPROTO_HOPOPTS
    IPPROTO_ICMP = 1,      
#define IPPROTO_ICMP        IPPROTO_ICMP
    IPPROTO_IGMP = 2,      
    ...
};

【问题讨论】:

  • 你不认为条件是用于启用/禁用功能,例如如果定义了IPPROTO_ICMP,则创建IPPROTO_ICMP 枚举并在协议栈中启用ICMP 协议。我在 LwIP 库中看到过类似的东西。
  • @MortenJensen 应该在任一情况下定义枚举,以便完成运行时检查,而不是使用库的每个应用程序都执行-DIPPROTO_xxxx=IPPROTO_xxxx
  • @CoffeeandCode 为什么您更喜欢运行时检查而不是编译时检查?我同意它的品味很差,我只是在猜测原作者的想法:)
  • @MortenJensen 编译时检查被编译到库中,运行时检查是为了确保协议被库的链接版本支持。无论如何都会有运行时检查,但可能会有 config.h 文件或类似文件用于与用户进行编译时检查。

标签: c enums constants c-preprocessor


【解决方案1】:

可能还有其他代码依赖于#ifdef IPPROTO_IP 等。

【讨论】:

  • 虽然这个答案很可能突出了真相的一方面,但另一方面仍然是一个问题:使用匿名enum 有什么好处?常数也可用作 CPP 值?为什么 CPP 值不够?
  • 作为语言级别而不是预处理器级别的构造,enum 不会被扩展/“内联”并且将保持符号化,更有可能出现在调试器中,保证其初始化值类型正确且常量(#defines 甚至不能保证是表达式,更不用说不可变或无副作用了)等等。
  • 另外,#ifdefs 存在的部分原因是因为the standard 这么说(对于netinet/in.h,它是 POSIX,但在 ISO 标准中也定义了一些宏): 头应定义以下 ....,ISO C 标准区分枚举成员宏名称。因此,只定义枚举成员而不定义宏名称,将不符合标准。
  • @anol 的回答似乎是正确的,考虑到宏是在枚举值之后添加的,相关提交:sourceware.org/git/…
猜你喜欢
  • 1970-01-01
  • 2010-10-11
  • 2011-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-12
  • 2019-10-24
  • 1970-01-01
相关资源
最近更新 更多