dra*_*oot 36 c c++ enums language-lawyer
说,我们有
enum E
{
Foo = 0,
Bar = 1
};
Run Code Online (Sandbox Code Playgroud)
现在,我们做到了
enum E v = ( enum E ) 2;
Run Code Online (Sandbox Code Playgroud)
然后
switch ( v )
{
case Foo:
doFoo();
break;
case Bar:
doBar();
break;
default:
// Is the compiler required to honor this?
doOther();
break;
}
Run Code Online (Sandbox Code Playgroud)
由于上面的开关处理枚举的每个可能列出的值,是否允许编译器优化掉default上面的分支,或者在enum的值不在列表中的情况下具有未指定或未定义的行为?
正如我期望C和C++的行为应该类似,问题在于两种语言.但是,如果在这种情况下C和C++之间存在差异,那么了解它也会很好.
Chr*_*phe 23
在C++中,每个枚举都有一个底层整数类型.它可以是固定的,如果它是明确指定的(ex :),enum test2 : long { a,b};或者如果是scoped enum(ex :)int的默认情况下它是固定的: enum class test { a,b };
[dcl.enum]/5:每个枚举定义一个与所有其他类型不同的类型.每个枚举也有一个基础类型.(...)如果未明确指定,则作用域枚举类型的基础类型为int.在这些情况下,据说基础类型是固定的.
对于没有明确修复底层类型的无范围枚举(您的示例),标准为您的编译器提供了更大的灵活性:
[dcl.enum]/7:对于其基础类型未修复的枚举,基础类型是一个整数类型,可以表示枚举中定义的所有枚举器值.(...)它是实现定义的,使用整数类型作为基础类型,除了基础类型不应大于int,除非枚举器的值不能适合int或unsigned int.
现在这是一件非常棘手的事情:枚举变量可以保存的值取决于底层类型是否已修复:
如果它已修复,"枚举的值是基础类型的值."
另外,它是可以容纳最小枚举器和最大枚举器的最小位域的最小值和最大值内的积分值.
你是第二种情况,虽然你的代码适用于大多数编译器,但是最小的位域大小为1,所以你可以肯定在所有兼容的C++编译器上保留的唯一值是介于0和1之间的值...
结论:如果要确保该值可以设置为2,则必须使枚举枚举枚举或显式指示基础类型.**
更多阅读:
C情况要简单得多(C11):
6.2.5/16:枚举包含一组命名的整数常量值.每个不同的枚举构成不同的枚举类型.
所以基本上,它是一个int:
6.7.2.2./2定义枚举常量值的表达式应为整数常量表达式,其值可表示为int.
有以下限制:
每个枚举类型应与char,有符号整数类型或无符号整数类型兼容.类型的选择是实现定义的,但应能够表示枚举的所有成员的值.
在 C 中,枚举器的类型为int 。因此,任何整数值都可以分配给枚举类型的对象。
来自 C 标准(6.7.2.2 枚举说明符)
3 枚举器列表中的标识符被声明为int类型的常量,并且可以出现在任何允许的地方。
在 C++ 中,枚举数具有定义它的枚举类型。在 C++ 中,您应该显式指定底层类型,或者编译器自行计算最大允许值。
来自 C++ 标准(7.2 枚举声明)
5 每个枚举都定义一个不同于所有其他类型的类型。每个枚举还有一个基础类型。可以使用 enum-base 显式指定底层类型;如果未显式指定,作用域枚举类型的基础类型为 int。在这些情况下,基础类型被认为是固定的。在枚举说明符的右大括号之后,每个枚举数都有其枚举的类型。
因此,在 C 中,枚举的任何可能值都是任何整数值。编译器可能不会优化删除默认标签的开关。
| 归档时间: |
|
| 查看次数: |
3995 次 |
| 最近记录: |