【问题标题】:Why does 'typeof enum constant' generate a warning when compared to a variable of enum type?与枚举类型的变量相比,为什么“typeof enum constant”会生成警告?
【发布时间】:2015-07-01 12:04:33
【问题描述】:

我有以下代码。

typedef enum {FOO, BAR} Baz;

int main()
{
    Baz f1 = FOO;
    typeof(FOO) f2 = FOO;
    return (f1 == f2);
}

我使用gcc -Wextra foo.c 进行的编译会产生警告提示

foo.c: In function ‘main’:
foo.c:7:13: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
 return (f1 == f2);
             ^

我的 gcc 版本

gcc --version
gcc (Ubuntu 4.9.2-10ubuntu13) 4.9.2

我该如何解决这个问题?

【问题讨论】:

标签: c gcc enums


【解决方案1】:

直接引用C11,章节§6.7.2.2枚举说明符

每个枚举类型都应与char、有符号整数类型或无符号整数类型兼容。类型的选择是实现定义的。

所以,枚举变量的类型 不是标准定义的。可以是以上任何一种。

OTOH,FOO 是一个枚举常量,typeof(FOO) 将给你int,作为标准要求

声明为枚举常量的标识符的类型为int

用作f2 的类型。

现在,如果 enum 在您的实现中是 unsigned int,那么 f1 也是如此,f2int

接下来,您会收到警告。

我该如何解决这个问题?

好吧,如果你将f2 的类型更改为typeof(Baz),它给出了枚举的类型,那么f1f2 的类型将是相同的。编译器会很高兴的。

SEE LIVE HERE

【讨论】:

  • 我做了一个小更新。枚举类型可以与char 或与any 有符号或无符号整数类型兼容。
【解决方案2】:

这是 C 标准中的一个已知“错误”。枚举constants 保证为int 类型,而枚举variables 为实现定义的整数类型。

See this 供参考。

【讨论】:

  • 他们为什么这样做而不是仅仅应用正常的提升规则(即它们可以是提升为 int 的任何类型)?
  • @Random832 在 C90 或更高版本的标准中从未给出任何理由。我想他们希望通过允许字节大小的枚举来节省内存,而且理论上在许多情况下拥有一个字节的枚举会很方便。在实践中,你永远不能编写依赖它的代码,因为这样的代码是不可移植的。这只是 C 标准中许多非常愚蠢的事情之一,就像各种隐式类型提升规则一样。
  • 是的,但是一个字节可以提升为一个整数。所以在实践中,几乎在任何表达式中,FOO 仍然会像 int 一样表现,即使它的类型确实是 enum 的类型。
  • 我认为它的方式是 enum 类型具有它可以容纳的所有值的显式枚举。但是使用枚举值作为位标志,按位或在一起是常见的做法,并且结果值不在该显式列表中。
猜你喜欢
  • 2017-09-21
  • 2021-06-13
  • 2021-12-24
  • 1970-01-01
  • 2020-09-30
  • 1970-01-01
  • 1970-01-01
  • 2016-12-26
  • 2012-12-01
相关资源
最近更新 更多