我更新物理模拟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,带来令人不快的后果。这很奇怪:
我的印象是枚举可以设置为超出其范围的值。
我们对-Wall(或-Wextra)没有任何警告,当看起来确实是枚举假设警告时。
有人可以告诉我为什么会这样吗?和/或哪些编译器标志会警告我们,或至少更改枚举的默认行为以允许此设置?
答案 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。