根据这篇SO帖子:
What is the size of an enum in C?
枚举类型有signed int
类型。
我想将枚举定义从signed int
转换为unsigned int
。
例如,在我的平台上,unsigned int
是32位宽。
我想创建一个枚举:
typedef enum hardware_register_e
{
REGISTER_STATUS_BIT = (1U << 31U)
} My_Register_Bits_t;
我的编译器抱怨上面的定义超出范围(适用于signed int
)。
如何声明unsigned int
enum
值?
答案 0 :(得分:4)
根据这篇SO帖子: C中枚举的大小是多少? 枚举类型已签署int类型。
enum
类型 可以int
类型,但它们不是int
在C. gcc
1) ,默认情况下enum
类型为unsigned int
。
enum
常量为int
,但enum
类型是实现定义的。
在您的情况下,enum
常量为int
,但您给它的值不适合int
。您不能在C中使用unsigned int
enum
个常量,因为C表示它们是int
。
<小时/> <子> 1)gcc实现定义的枚举类型文档:“通常,如果枚举中没有负值,则类型为unsigned int,否则为http://gcc.gnu.org/onlinedocs/gcc/Structures-unions-enumerations-and-bit_002dfields-implementation.html
中的int”
子>
答案 1 :(得分:2)
不幸的是,ISO C标准(c99 6.4.4.3)规定枚举常量的类型为int
。如果您使用例如gcc -W -std=c89 -pedantic
,它会发出警告ISO C restricts enumerator values to range of ‘int’ [-pedantic]
。某些嵌入式编译器可能根本不接受代码。
如果您的编译器属于挑剔种类,您可以使用
解决问题typedef enum hardware_register_e
{
REGISTER_STATUS_BIT = -2147483648 /* 1<<31, for 32-bit two's complement integers */
} hardware_register_t;
但只有当int
是您体系结构上的32位二进制补码类型时,它才能正常工作。它是我曾经使用或听过的所有32位和64位架构。
编辑添加:ARM7使用32位二进制补码int
类型,因此上述应该可以正常工作。我只建议您保留评论,说明实际值为1<<31
。你永远不知道是否有人移植代码,或使用其他编译器。如果新编译器发出警告,则同一行上的注释应该使修复变得微不足道。就个人而言,我将代码包装在条件中,也许
typedef enum hardware_register_e
{
#ifdef __ICCARM__
REGISTER_STATUS_BIT = -2147483648 /* 1<<31, for 32-bit two's complement integers */
#else
REGISTER_STATUS_BIT = 1 << 31
#endif
} hardware_register_t;
答案 2 :(得分:1)
检查您的编译器是否有选项或编译指示使枚举无符号。如果没有,那么您只需使用普通unsigned int
(或固定宽度类型,例如uint32_t
)而不是枚举,#define
用于定义它可以采取的值。
答案 3 :(得分:1)
你不能(至少可以移植)改变枚举的类型。标准很清楚,枚举常量的类型为int
。要消除警告,您可以使用演员:
typedef enum hardware_register_e
{
REGISTER_STATUS_BIT = (int)(1U << 31U)
} My_Register_Bits_t;
可能的替代方案
如果这不必在标题中,您可以使用所需类型的const
对象而不是枚举常量:
const unsigned int REGISTER_STATUS_BIT = (1U << 31);
否则,您可以使用define:
#define REGISTER_STATUS_BIT (1U << 31)