简体   繁体   English

如何将枚举与其第零个值进行比较?

[英]How do I compare an enum with its zeroth value?

In c, it is not defined by the standard whether enums are signed or unsigned.在 c 中,标准没有定义枚举是有符号还是无符号。 However, when I try to compare an enum value to the lowest (ie 0) enumeration constant, I get the warning "pointless comparison of unsigned integer with zero."但是,当我尝试将枚举值与最低(即 0)枚举常量进行比较时,我收到警告“无符号整数与零的无意义比较”。 (Compiler is IAR embedded workbench.) (编译器是 IAR 嵌入式工作台。)

typedef enum
{
    BAR,
    BAZ
} Foo;

//later...
Foo x = (Foo)some_integral_value;
if (x >= BAR) // <- this gives me the warning
    //stuff

I need to check the range of the enum, however, because it is being converted from an integral type.但是,我需要检查枚举的范围,因为它是从整数类型转换而来的。 Is there a good way to do this that avoids the warning, which will still work if the compiler decides to change the underlying type?是否有避免警告的好方法,如果编译器决定更改基础类型,它仍然有效?

In C this is a false problem. 在C语言中,这是一个错误的问题。

  • all enumeration constants are always of type int , anyhow 无论如何,所有枚举常量始终为int类型
  • conversions back and forth the enumeration type work easily with implicit conversion, no explicit conversions (AKA cast) are necessary nor desirable 来回转换枚举类型与隐式转换很容易,不需要显式转换(也称为AKA强制转换)

Now to your example 现在到你的例子

enum Foo
{
    BAR,
    BAZ
};

//later...
Foo x = (Foo)some_integral_value;

This doesn't even compile, because in C Foo is not defined to be anything, you must use enum Foo , or provide an appropriate typedef , something like 这甚至不会编译,因为在C Foo中没有将其定义为任何东西,您必须使用enum Foo或提供适当的typedef ,例如

typedef enum Foo Foo;

Perhaps you compile C code with a C++ compiler? 也许您使用C ++编译器来编译C代码? In any case, provide a complete example that shows your problem. 无论如何,请提供一个完整的示例来说明您的问题。

It sounds like in C, all enums should have type int , but I'm leaving these suggestions around, since your compiler is either non-standard C, or compiling as C++. 听起来像在C语言中,所有枚举都应具有int类型,但是我遗漏了这些建议,因为您的编译器是非标准C或编译为C ++。


If you have control over the definitions of these enums, you could just make them start at 1: 如果您可以控制这些枚举的定义,则可以使它们从1开始:

enum Foo
{
    BAR = 1,
    BAZ
};

You could also add a single fake negative value to force it to be signed: 您还可以添加一个假的负值以强制对其进行签名:

enum Foo
{
    NEGATIVE_PLACEHOLDER = -1,
    BAR,
    BAZ,
};

In C++11, you can give your enum an explicit underlying type: 在C ++ 11中,可以给枚举一个显式的基础类型:

enum Foo : int
{
    BAR,
    BAZ
};

See this page , specifically the section that says: 请参阅此页面 ,特别是显示以下内容的部分:

enum name : type { enumerator = constexpr , enumerator = constexpr , ... }

... ...

2) declares an unscoped enumeration type whose underlying type is fixed 2)声明一个无范围的枚举类型,其基础类型是固定的

It sounds like the type should always be predictable though: 听起来类型应该始终是可预测的:

Values of unscoped enumeration type are implicitly-convertible to integral types. 非范围枚举类型的值可以隐式转换为整数类型。 If the underlying type is not fixed, the value is convertible first type from the following list able to hold their entire value range: int , unsigned int , long , unsigned long , long long , or unsigned long long . 如果基础类型不是固定的,则该值是以下列表中可转换的第一类型,该类型可以保留其整个值范围: intunsigned intlongunsigned longlong longunsigned long long If the underlying type is fixed, the values can be converted to their promoted underlying type. 如果基础类型是固定的,则可以将值转换为其提升的基础类型。

So, if your enum fits in an int , it should always use an int . 因此,如果您的枚举适合int ,则应始终使用int

Brendan's first comment is applicable to C and does answer the question. 布伦丹的第一个评论适用于C和不回答这个问题。 That is, forcing the value of the first item in the enum to 1 eliminates the compile warning. 也就是说,将枚举中第一项的值强制为1可以消除编译警告。 Whether or not this is a viable answer in the original poster's situation depends upon whether or not the first value has to be zero for some other reason. 在原始发布者的情况下,这是否是一个可行的答案取决于第一个值是否必须由于其他原因而为零。

ps Sorry for posting a response to the question instead of to the answer I'm commenting on but Stack Overflow won't let me do the latter. ps对不起,我没有评论我所评论的问题,而是发布了对问题的答复,但是Stack Overflow不允许我这样做。

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

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