【问题标题】:Why define a macro with the same name and content in C? [duplicate]为什么要在 C 中定义一个名称和内容相同的宏? [复制]
【发布时间】:2017-07-08 00:22:10
【问题描述】:

我正在查看 Linux 内核头文件中的 if_link.h,它包含这个枚举:

enum {
        IFLA_UNSPEC,
        IFLA_ADDRESS,
        IFLA_BROADCAST,
        IFLA_IFNAME,
        IFLA_MTU,
        IFLA_LINK,
        IFLA_QDISC,
        IFLA_STATS,
        IFLA_COST,
#define IFLA_COST IFLA_COST
        IFLA_PRIORITY,
#define IFLA_PRIORITY IFLA_PRIORITY
        IFLA_MASTER,
#define IFLA_MASTER IFLA_MASTER
....
}

定义看起来没用;他们的目的是什么?为什么只有部分项目有定义?

【问题讨论】:

  • 也许代码在某处使用了#ifdef IFLA_COST
  • 也许曾经有一个define 被更改为一个枚举,这只是为了向后兼容。你试过git blame吗?
  • 我的猜测是那些枚举值是后来添加的,所以定义是这样的,所以代码可以使用 ifdef 来查看它们是否存在。
  • 这能回答你的问题吗? What does it mean by "#define X X"?

标签: c macros c-preprocessor


【解决方案1】:

正如 Matthew Slattery mentioned in another answer,GCC 手册中有一个部分,即 §3.10.5 Self-Referential Macros,描述了此类宏的可能用途。

当宏扩展为对其自身的调用时,一种可能的用途是避免无限扩展,但这是一种不鼓励的做法。另一个用途是定义预处理器宏和枚举:

如果你想用枚举定义数字常量,你可以这样做,但每个常量的 `#ifdef' 为真。

所以这基本上就是M.M在上面的评论中所说的。

这似乎得到this patch的证实:

为什么内核开发人员的行为如此不一致?我很 更喜欢将枚举值也添加为定义的接口 本身,以便于探查哪些功能是可用的 当前的标题集。

真正令人沮丧的部分是 其中的一些枚举值 set 有#defines,其中一些没有。

【讨论】:

    【解决方案2】:

    IPv4 协议 中使用的此宏提供了创建、删除或获取有关特定网络接口的信息的能力。见man page

    【讨论】:

    • 这并不能真正解释为什么会有宏和枚举的混合。我在链接中没有找到任何关于此的内容,但也许我错过了。你能引用手册页的相关部分吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 2013-11-13
    相关资源
    最近更新 更多