C语言中使用32位值的枚举类型

6

我需要一些无符号32位枚举值来支持我的软件,因此我实现了以下简单的枚举:

enum{
   val1    = 0xFFFFFFFFu,
   val2    = 0xFFFFFFFEu,
   val3    = 0xFFFFFFF0
};

问题:每次运行编译器时,Eclipse都会中止编译并标记枚举与以下错误:
enter image description here
在我看来,32个 int 值不应该成为枚举的问题,但显然它似乎是。 我会非常感激一些意见 :)

[更新1:] 我将尝试在编译器设置中找到问题,并随时向您更新。


2
它在抱怨,因为你试图为有符号整数使用无符号字面量。 - Colin
你使用哪个编译器?你能编辑你的代码并展示一个 [MCVE] 吗? - Jabberwocky
这里可以编译:http://ideone.com/Scfu6X - Jabberwocky
2
既然我们已经在吹嘘编译器了,clang也可以。 - riodoro1
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Lundin
显示剩余8条评论
3个回答

6
一个枚举常量(你的例子中的 val1)需要按C标准为 int 类型。这是一个有符号类型,在32位系统上,值 FFFFFFFF 将无法容纳在其中。因此,将以某种实现定义的(特定于编译器的)方式将该值转换为带符号整数。如果无法执行此操作,则会得到一个实现定义的信号。
编写依赖于此的代码是不好的,因为它是不可移植和不可预测的。没有任何编译器设置可以解决这个问题,因为这是语言设计的规定。
我认为可以删除 gcc 标志 -pedantic/-pedantic-errors 以消除警告,但这是一个坏主意,因为您将不再遵循标准 C。默认情况下,gcc 以其非标准的“臭鼬模式”-std=gnu90 或 -std=gnu11 编译代码,任何不带 -pedantic-errors 的 -std=cxx 都会编译代码。
这就是为什么枚举类型不适用于任何形式的位掩码或位运算。最好的解决方案是摆脱枚举并使用 #define 或 const uint32_t,具体取决于您的特定场景。

2
它们适用于不使用符号位的位掩码。 - M.M
我尚未发现任何编译器在使用“-pedantic-errors”时对 OP 的代码提出抱怨。我不知道我们需要加哪个标志才能在编译该代码时得到警告/错误提示。 - Jabberwocky
2
@M.M 不,它们确实不是,例如考虑 mask << n~mask - Lundin
1
@MichaelWalz,那你肯定做错了什么。gcc -std=c11 -pedantic-errors会报错:error: ISO C restricts enumerator values to range of 'int' [-Wpedantic] - Lundin
2
@MichaelWalz 所有我尝试过的gcc版本都会在使用-pedantic时给出警告...也许你是在尝试C++编译器,或者在线编译器抑制了警告。 - M.M
@Jabberwocky:FYI - http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0348c/Babjddhe.html “#66:枚举值超出'int'范围”ARM编译器会生成此警告。另外,注意C语言的行为是实现定义。编译器有没有警告都是由编译器决定的。如果编译器生成了一个警告,那么它就很友好了。 - Cheshar

3
你试过这个吗?:
enum {
   val1    = (int)0xFFFFFFFFu,
   val2    = (int)0xFFFFFFFEu,
   val3    = (int)0xFFFFFFF0
};

编辑:我刚在cygwin上安装了gcc并尝试了这个。

test-enum.c是原始版本,test-enum-int.c是具有显式转换的版本:

$ cc -std=c11 -pedantic-errors -c test-enum.c
test-enum.c:2:8: error: ISO C restricts enumerator values to range of 'int' [-Wpedantic]
   val1 = 0xFFFFFFFFu,
          ^
test-enum.c:3:8: error: ISO C restricts enumerator values to range of 'int' [-Wpedantic]
   val2 = 0xFFFFFFFEu,
          ^
test-enum.c:4:8: error: ISO C restricts enumerator values to range of 'int' [-Wpedantic]
   val3 = 0xFFFFFFF0u
          ^

$ cc -std=c11 -pedantic-errors -c test-enum-int.c

(no complains)

$ cc --version
cc (GCC) 5.4.0
Copyright (C) 2015 Free Software Foundation, Inc.

这意味着完全相同的事情。警告是有原因的。 - Lundin
1
@Lundin 在我看来,这并不完全相同。然而,我同意以这种方式强制使用C编译器应该小心谨慎,并且可能会限制可移植性。 - Scheff's Cat
1
强制类型转换肯定会改变值。标准只允许明确进行转换。请注意,转换的结果取决于具体实现;我们默认使用二进制补码。 - Potatoswatter

0

之前有人说要使用ideaone.com,但他们的代码是错误的。 你必须实际使用枚举才能得到错误:

#include <stdio.h>
 
enum{
   val1    = 0xFFFFFFFFu,
   val2    = 0xFFFFFFFEu,
   val3    = 0xFFFFFFF0
} abc ;
 
int main(void) {
 
    abc mine = val1;
    return 0;
}

你可以将枚举限制在带符号的整数0x7FFFFFFF内。

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