【问题标题】:Typedef and enum with same name?Typedef和枚举具有相同的名称?
【发布时间】:2015-05-29 04:13:03
【问题描述】:

在库FreeImagePlusFreeImage.h 中,有一个有趣的#define 似乎创建了一个typedef 和一个enum 同名:

#define FI_ENUM(x)      typedef int x; enum x

这被预处理器扩展为如下代码:

typedef int FREE_IMAGE_FILTER;
enum FREE_IMAGE_FILTER {
 FILTER_BOX = 0,
 FILTER_BICUBIC = 1,
[...]

这是做什么的?拥有同名的typedefenum 是否合法? 而且enum 不兼容int 吗?为什么 FreeImage 会这样做?

【问题讨论】:

    标签: c enums typedef freeimage


    【解决方案1】:

    结构、联合和枚举的名称存在于它们自己的命名空间中。这就是为什么你可以声明一个与实际 struct/union/enum 同名的 struct/union/enum 变量。

    这不是必须与整数兼容的完整enum 的名称(例如enum X 我的意思是X),而是枚举中的名称​​inside

    【讨论】:

    • 谢谢,不知道命名空间。不过,“typedef int”在哪里有帮助?有没有没有它的代码?
    • @sleske 一般不需要,你还不如typedef enum X { ... } X; 除非有对X 类型的变量的操作不能对枚举类型进行。
    【解决方案2】:

    引用C99 N1256 draft 6.2.1“标识符范围”:

    一个标识符可以表示一个对象;一个函数;结构、联合或枚举的标签或成员;类型定义名称;标签名称;宏名;或宏参数。

    这意味着在:

    typedef int id;
    

    id 是一个标识符。

    从 6.2.3 “标识符的命名空间”开始:

    开始报价

    如果一个特定标识符的多个声明在翻译单元中的任何位置可见,则句法上下文消除了引用不同实体的用法的歧义。因此,不同类别的标识符有单独的名称空间,如下所示:

    • 标签名称(通过标签声明和使用的语法消除歧义);
    • 结构、联合和枚举的标签(通过任何关键字 struct、union 或 enum 来消除歧义);
    • 结构或工会的成员;每个结构或联合对其成员都有一个单独的名称空间(通过用于通过 . 或 -> 运算符访问成员的表达式的类型来消除歧义);
    • 所有其他标识符,称为普通标识符(在普通声明符中声明或作为枚举常量声明)。

    结束报价

    所以在:

    typedef int id;
    enum id {ID0};
    
    • 第一个id是一个普通的标识符
    • 第二个是标签标识符

    两者可以和平共处。

    另一方面,我们不能这样做:

    typedef int id;
    int id;
    

    因为两者都是普通标识符。

    【讨论】:

      猜你喜欢
      • 2023-03-18
      • 2020-04-05
      • 2013-05-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多