C枚举类型名称作用域

4

GCC告诉我,你不能将不同的枚举类型值使用相同的名称,例如:

enum flag_one {
    SUCCESS,
    FAIL
}

enum flag_two {
    SUCCESS,
    FAIL
}

编译器不允许这样做。因此,作用域不在枚举定义内部吗?

解决方法是像这样进行:

enum flag_one {
    FLAG_ONE_SUCCESS,
    FLAG_ONE_FAIL
}

enum flag_two {
    FLAG_TWO_SUCCESS,
    FLAG_TWO_FAIL
}

我有点困惑,因为我喜欢使用枚举来返回整数代码,因为这样更易读/描述性,但我已经开始出现名称冲突。


为什么需要创建两个枚举?编译器不会对你的枚举进行任何类型检查。 - David Heffernan
我正在使用每个函数一个枚举来定义允许返回int集合并赋予它们有意义的名称。看起来很有道理,直到我遇到了名称冲突的问题,我认为作用域意味着在同一枚举中不能具有相似的名称,但在不同的枚举中具有相似的名称是可以的。我想我误解了枚举的工作方式。 - bph
我认为使用多个枚举有助于简化代码的阅读,即将返回整数及其描述按函数分组。如果我把它们全部放在一个枚举中,那么这将是一个很长的枚举,你将失去查看哪些返回整数属于哪个函数的能力。 - bph
但是,如果常量具有相同的值和含义(成功/失败或类似),那还有什么意义呢?将枚举放在.h文件中,包含并始终使用它...如果含义不同,则名称也应该不同... - ShinTakezou
这是一个C语言问题。它并没有像C++的::作用域运算符那样。即使作用域按照你想的方式工作,你怎么可能解决歧义呢? - jamesdlin
2个回答

6
所以,作用域不在枚举定义内部吗?
不是的。这是不允许的。枚举列表定义常量。你的enum恰好在同一作用域——文件作用域中。你不能在同一作用域中有两个相同名称的常量。
来自CX草案:
6.7.2.2枚举说明符
语义
3、枚举列表中的标识符被声明为具有int类型的常量,并且可以出现在任何允许出现的地方127)。[...]
另外,来自脚注127(技术上非规范性的,仅供信息参考):
127)因此,在同一作用域中声明的枚举常量的标识符应互不相同,并且与在普通声明符中声明的其他标识符不同。
略微困惑,因为我喜欢使用枚举返回整数代码[...]
使用stdlib.h中定义的EXIT_SUCCESS和EXIT_FAILURE。

如果枚举位于不同的文件中,您会使用 static 关键字以确保它们处于不同的“文件作用域”吗? - bph
1
enum 是一种类型,因此 static(或任何存储期)都没有意义。 - dirkgently
只是重新审视这个问题,相同的枚举常量名称在同一文件中是不行的,但如果在不同的文件中是否可以呢?我现在会进行测试。 - bph

3
枚举值在枚举类型的范围内可见。这意味着它们在该范围内必须是唯一的。
其他语言(如C++11)添加了一种新的枚举类型enum class,其中值在封闭范围内不直接可见。
您需要编写flag_one::SUCCESSflag_two::SUCCESS才能获取这些值,因此与第二个选项相比没有太大区别。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接