在C语言中(C99),使用枚举类型来避免名称冲突。

11

enum元素的名称容易与其他enum元素名称、变量名称等发生重叠/冲突...

enum Fruit
{
    apple,
    orange
};
typedef enum Fruit Fruit;


enum Color
{
    red,
    orange // <-- ERROR
};
typedef enum Color Color;


char apple='a'; // <-- ERROR

除了在每个枚举元素名称前缀上,是否有符合C99标准的避免冲突解决方案?


顺便提一下:这个问题已经在C++中有答案。

如何避免C++中具有相同名称的两个枚举值的名称冲突?

我正在寻找一种C99的解决方案。


是的,请使用适当的名称,如color_orangefruit_orange。这也应该避免阅读时的混淆。 - Iharob Al Asimi
除了给每个枚举元素名称添加前缀之外,是否有其他解决方案? - Paolo
可能可以,但这很可能是一个糟糕的解决方案,而这个好的解决方案还有助于提高可读性。 - Iharob Al Asimi
有没有比 Fruit f = orange;Color c = orange; 更易读的方式?这样做很整洁,毫无疑问 f 是水果,c 是颜色。 - Paolo
1
是的,Fruit fruit = FruitOrange;。在这种情况下,switch (fruit) {case FruitOrange: break ...}。如果有很多水果,您会很高兴为它们添加前缀。此外,f可以表示filef**ck和许多其他以f开头的单词,而fruit则只是简单的fruit - Iharob Al Asimi
显示剩余4条评论
1个回答

11

在C语言中,除了使用枚举值的前缀之外,没有其他解决方案。

正如OP所指出的那样,C++有许多机制,其中enum class可能适用于现代代码。然而,在实践中,结果是相同的:您最终会将枚举元素的名称与枚举的名称作为前缀。可以说,Fruit::orangeFruitOrange更整洁,但对我来说并没有太大区别。

在某些平行宇宙中,拥有一种能够编写以下内容的语言真的很棒:

Fruit selected = orange;

可以让编译器推断右侧常量的名称空间,但我不认为这种语言可能是C。在那个意义上,C没有命名空间,即使有,类型系统也只允许转换;你不能基于左侧的语法条件RHS的语法(我故意使用语法一词,因为在C中名称查找是一个语法属性)。

即使您确实有一些语言黑客技巧,有时会隐式插入枚举名称空间,您仍然需要在任何比较中显式前缀,因为

if (apple > orange)

虽然C语言中枚举值的类型都是int,这使得FruitAppleFruitOrange可比较,但是它们并没有可以进行推断的上下文。


1
只想添加一个链接,以补充这个答案:https://dev59.com/p6jja4cB1Zd3GeqP6ysC#48231009 - sdbbs
有人声称 Namespace::variableNameNamespace.variable_name 更加“漂亮”或“好看”,但并未指定用于做出这些主观判断的度量标准。一个简单的 Namespace_variable 可以完成同样的功能,打字更少。如果语言支持,NamespaceVariable 也可以使用。除非额外的类型信息可以与 enum class 或等效物一起使用,否则这主要是个人喜好。 - SO_fix_the_vote_sorting_bug
在C++20中,你不必强制使用枚举名称来定义作用域枚举 - using关键字可以让你直接将枚举引入作用域。 例如:using enum Fruit; Fruit f = orange; - ABaumstumpf

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