Typedef和enum具有相同的名称?

时间:2013-07-29 07:35:06

标签: c enums typedef freeimage

FreeImagePlus库中FreeImage.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是否合法? 并不是enumint兼容吗?为什么FreeImage会这样做?

2 个答案:

答案 0 :(得分:7)

结构,联合和枚举的名称存在于它们自己的命名空间中。这就是为什么您可以使用与实际struct / union / enum相同的名称声明struct / union / enum变量。< / p>

并且它不是完整enum的名称(例如,对于enum X我的意思是X)必须与整数兼容,它是名称​​ inside < / em>枚举。

答案 1 :(得分:0)

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

  

标识符可以表示对象;功能;标签或结构,联合或枚举的成员;一个typedef名称;标签名称;一个宏名;或宏参数。

表示在:

typedef int id;

id是一个标识符。

从6.2.3“标识符的名称空间”:

BEGIN QUOTE

如果在翻译单元中的任何一点可以看到多个特定标识符的声明,则语法上下文消除了引用不同实体的用法。因此,各种标识符类别都有单独的名称空间,如下所示:

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

结束语录

所以:

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

两者可以和平共处。

另一方面,我们做不了类似的事情:

typedef int id;
int id;

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