C 枚举警告
C Enum 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 中编译时,这会导致静默失败;该值设置为未定义,而不是 -1,会带来不愉快的后果。这很奇怪,因为:
我的印象是枚举 可以 设置为超出其范围的值。
我们使用 -Wall(或 -Wextra)没有收到关于此的警告,当枚举似乎 应该 警告时。
谁能告诉我为什么会这样? And/or 哪些编译器标志会警告我们这一点,或者至少更改枚举的默认行为以允许此设置?
您的程序的行为可能因平台而异:
C 标准允许编译器为能够表示所有给定显式值的枚举器选择任何基础整数类型:在您的情况下为 1 和 2。
因此编译器可能为您的枚举选择一个无符号类型。在这种情况下分配负值会导致环绕模 2^n,其中 n 是用于表示无符号类型的位数。
另一方面,它可能选择一个带符号的类型,在这种情况下 -1 可以表示。
一种补救措施是在您的枚举器中引入负虚拟值。
我看到你的问题了。我认为它在被设置为另一个枚举值之前被初始化为一个未定义的值 -1,对吗?我建议添加另一个枚举值 SPEC_MOD_UNDEFINED。然后你可以简单地首先将它初始化为那个,然后再设置为另一个。
此外,如果你想遍历所有枚举值,在末尾添加一个 NUM_SPEC_MOD 是可行的,这将取比之前指定的最后一个更大的数字。
然后你可以做一个
for(int i = SPEC_MOD_PL; i < NUM_SPEC_MOD;i++)
超过所有值。并且只在必要时为枚举分配特定值,它会自动自动完成。但是看到您修改了现有代码,我明白了为什么您可能想要添加特定数字。对于我的例子,数字必须是上升的整数值,以便所有数字都指向某个状态。
之所以可行,是因为 C 直接向程序员公开了枚举值的整数表示形式。整数和枚举值可以自由混合,并且允许对枚举值进行所有算术运算。 枚举变量甚至可以保存一个不代表任何枚举值的整数。事实上,根据语言定义,您的代码将定义SPEC_MOD_PL和 SPEC_MOD_EXP 作为 int 类型的常量,只有当它们存储在该类型的变量中时才会(静默地)转换为枚举 spec_mod_type。
我正在更新一个物理模拟 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 中编译时,这会导致静默失败;该值设置为未定义,而不是 -1,会带来不愉快的后果。这很奇怪,因为:
我的印象是枚举 可以 设置为超出其范围的值。
我们使用 -Wall(或 -Wextra)没有收到关于此的警告,当枚举似乎 应该 警告时。
谁能告诉我为什么会这样? And/or 哪些编译器标志会警告我们这一点,或者至少更改枚举的默认行为以允许此设置?
您的程序的行为可能因平台而异:
C 标准允许编译器为能够表示所有给定显式值的枚举器选择任何基础整数类型:在您的情况下为 1 和 2。
因此编译器可能为您的枚举选择一个无符号类型。在这种情况下分配负值会导致环绕模 2^n,其中 n 是用于表示无符号类型的位数。
另一方面,它可能选择一个带符号的类型,在这种情况下 -1 可以表示。
一种补救措施是在您的枚举器中引入负虚拟值。
我看到你的问题了。我认为它在被设置为另一个枚举值之前被初始化为一个未定义的值 -1,对吗?我建议添加另一个枚举值 SPEC_MOD_UNDEFINED。然后你可以简单地首先将它初始化为那个,然后再设置为另一个。
此外,如果你想遍历所有枚举值,在末尾添加一个 NUM_SPEC_MOD 是可行的,这将取比之前指定的最后一个更大的数字。
然后你可以做一个
for(int i = SPEC_MOD_PL; i < NUM_SPEC_MOD;i++)
超过所有值。并且只在必要时为枚举分配特定值,它会自动自动完成。但是看到您修改了现有代码,我明白了为什么您可能想要添加特定数字。对于我的例子,数字必须是上升的整数值,以便所有数字都指向某个状态。
之所以可行,是因为 C 直接向程序员公开了枚举值的整数表示形式。整数和枚举值可以自由混合,并且允许对枚举值进行所有算术运算。 枚举变量甚至可以保存一个不代表任何枚举值的整数。事实上,根据语言定义,您的代码将定义SPEC_MOD_PL和 SPEC_MOD_EXP 作为 int 类型的常量,只有当它们存储在该类型的变量中时才会(静默地)转换为枚举 spec_mod_type。