C枚举警告

时间:2015-08-06 12:02:37

标签: c enums compiler-warnings

我更新物理模拟C代码以使用来自#defines长列表的枚举,但遇到了一个奇怪的错误。 结构包含枚举为:

enum spec_mod_type_enum 
{ SPEC_MOD_PL=1, 
  SPEC_MOD_EXP=2,
} spec_mod_type[NXBANDS];

(NXBANDS只是一个#defined值)

由于疏忽,没有为-1添加密钥,而在另一个文件中,它被修改为:

xplasma->spec_mod_type[n] = -1;

然而,当在clang和gcc中编译时,这会导致无声失败;该值设置为undefined,而不是-1,带来令人不快的后果。这很奇怪:

  1. 我的印象是枚举可以设置为超出其范围的值。

  2. 我们对-Wall(或-Wextra)没有任何警告,当看起来确实是枚举假设警告时。

  3. 有人可以告诉我为什么会这样吗?和/或哪些编译器标志会警告我们,或至少更改枚举的默认行为以允许此设置?

2 个答案:

答案 0 :(得分:7)

您的程序的行为可能因平台而异:

C标准允许编译器为枚举数选择任何基础整数类型,它能够表示给定的所有显式值:在你的情况下为1和2。

因此,编译器可能会为您的枚举选择一个无符号类型。在这种情况下分配负值将导致环绕模2 ^ n,其中n是用于表示无符号类型的位数。

另一方面,可能选择一个签名类型,在这种情况下-1可以表示。

一种补救方法是在您的枚举器中引入负虚拟值。

答案 1 :(得分:0)

我看到了你的问题。我认为它在被设置为另一个枚举值之前被初始化为未定义的值-1,对吧?我建议添加另一个枚举值SPEC_MOD_UNDEFINED。然后你可以先把它初始化为那个,然后再设置为另一个。

此外,如果您想迭代所有枚举值,最后在末尾添加一个NUM_SPEC_MOD是可行的,然后将比前一个指定的值高一号。

然后你可以做一个

for(int i = SPEC_MOD_PL; i < NUM_SPEC_MOD;i++)

超过所有价值观。并且只在必要时为枚举分配特定值,它会自动执行此操作。但是,看到您修改现有代码,我明白为什么您可能想要添加特定数字。对于我的例子,数字必须是上升的整数值,以便所有数字都指向某个状态。

这是有效的,因为C将枚举值的整数表示直接暴露给程序员。整数和枚举值可以自由混合,并且允许对枚举值进行所有算术运算。 enum变量甚至可以保存一个不代表任何枚举值的整数。实际上,根据语言定义,您的代码将SPEC_MOD_PL和SPEC_MOD_EXP定义为int类型的常量,如果它们存储在该类型的变量中,则只会(默默地)转换为枚举spec_mod_type。

from Wikipedia Enumerated type article