简体   繁体   English

将枚举定义转换为unsigned int

[英]Casting enum definition to unsigned int

According to this SO post: 根据这篇SO帖子:
What is the size of an enum in C? C中枚举的大小是多少?
enum types have signed int type. 枚举类型已signed int类型。

I would like to convert an enum definition from signed int to unsigned int . 我想将一个enum定义从signed int转换为unsigned int

For example, on my platform an unsigned int is 32-bits wide. 例如,在我的平台上, unsigned int是32位宽。 I want to create an enum: 我想创建一个枚举:

typedef enum hardware_register_e
{
    REGISTER_STATUS_BIT = (1U << 31U)
} My_Register_Bits_t;

My compiler is complaining that the above definition is out of range (which it is for a signed int ). 我的编译器抱怨上面的定义超出了范围(它适用于signed int )。

How do I declare unsigned int enum values? 如何声明unsigned int enum值?

Edit 1: 编辑1:

  1. The preference is not to expand to 64 bits (because the code resides in an embedded system). 首选项不是扩展到64位(因为代码驻留在嵌入式系统中)。
  2. Due to skill limitations, C++ is not allowed for this project. 由于技能限制,此项目不允许使用C ++。 :-( :-(

Edit 2: 编辑2:

  • Compiler is IAR Embedded Workbench for ARM7. 编译器是ARM​​7的IAR Embedded Workbench。

According to this SO post: What is the size of an enum in C? 根据这篇SO帖子:C中枚举的大小是多少? enum types have signed int type. 枚举类型已签署int类型。

The thing is enum types can be int type but they are not int in C. On gcc 1) , enum types are unsigned int by default. 东西是enum类型可以int类型但它们在C中不是int 。在gcc 1)上enum类型默认为unsigned int

enum constants are int but enum types are implementation defined. enum常量是intenum类型是实现定义的。

In your case the enum constant is int but you are giving it a value that does not fit in a int . 在你的情况下, enum常量是int但你给它一个不适合int You cannot have unsigned int enum constants in C as C says they are int . 你不能在C中使用unsigned int enum常量,因为C表示它们是int


1) gcc implementation defined enum type documentation: "Normally, the type is unsigned int if there are no negative values in the enumeration, otherwise int" in http://gcc.gnu.org/onlinedocs/gcc/Structures-unions-enumerations-and-bit_002dfields-implementation.html 1)gcc实现定义的枚举类型文档:“通常,如果枚举中没有负值,则类型为unsigned int,否则为int”,请参阅http://gcc.gnu.org/onlinedocs/gcc/Structures-unions-enumerations -and-bit_002dfields-implementation.html

Unfortunately ISO C standard (c99 6.4.4.3) states that the enumeration constants are of type int . 遗憾的是,ISO C标准(c99 6.4.4.3)规定枚举常量的类型为int If you compile the above with eg gcc -W -std=c89 -pedantic , it will issue a warning ISO C restricts enumerator values to range of 'int' [-pedantic] . 如果使用例如gcc -W -std=c89 -pedantic编译上述gcc -W -std=c89 -pedantic ,它将发出警告ISO C restricts enumerator values to range of 'int' [-pedantic] Some embedded compilers may not accept the code at all. 某些嵌入式编译器可能根本不接受代码。

If your compiler is of the pickier variety, you can workaround the issue by using 如果您的编译器具有挑剔性,则可以使用以解决该问题

typedef enum hardware_register_e
{
    REGISTER_STATUS_BIT = -2147483648   /* 1<<31, for 32-bit two's complement integers */
} hardware_register_t;

but it works correctly only if int is 32-bit two's complement type on your architecture. 但只有当int是您体系结构中的32位二进制补码类型时,它才能正常工作。 It is on all 32-bit and 64-bit architectures I have ever used or heard of. 它是我曾经使用或听过的所有32位和64位架构。

Edited to add: ARM7 uses 32-bit two's complement int type, so the above should work fine. 编辑补充:ARM7采用32位二进制补码int类型,所以上面的应该能正常运行。 I only recommend you keep the comment explaining that the actual value is 1<<31 . 我只建议你保留评论说明实际值是1<<31 You never know if somebody ports the code, or uses another compiler. 你永远不知道是否有人移植代码,或使用其他编译器。 If the new compiler issues a warning, the comment on the same line should make it trivial to fix. 如果新编译器发出警告,则同一行上的注释应该使修复变得微不足道。 Personally, I'd wrap the code in a conditional, perhaps 就个人而言,我可能会在有条件的情况下将代码包装起来

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;

Check if your compiler had an option or a pragma to make enums unsigned. 检查您的编译器是否有选项或编译指示使枚举无符号。 If it doesn't, then you'll just have to use a plain unsigned int (or a fixed-width type such as uint32_t ) instead of an enum, with #define s used to define the values it can take. 如果没有,那么你只需要使用普通的unsigned int (或固定宽度类型,如uint32_t )而不是enum,使用#define来定义它可以采用的值。

You can't (at least portably) change the type of enum. 你不能(至少可以移植)改变枚举的类型。 The standard is clear that an enumeration constant has type int . 标准很清楚,枚举常量的类型为int To get rid of the warning you can use a cast: 要消除警告,您可以使用强制转换:

typedef enum hardware_register_e
{
    REGISTER_STATUS_BIT = (int)(1U << 31U)
} My_Register_Bits_t;

Possible Alternatives 可能的替代方案

If this doesn't have to be in a header, you can use a const object of required type instead of enumeration constant: 如果不必在头文件中,则可以使用所需类型的const对象而不是枚举常量:

const unsigned int REGISTER_STATUS_BIT = (1U << 31);

Otherwise, you can use a define: 否则,您可以使用define:

#define REGISTER_STATUS_BIT (1U << 31)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM