c – 强制枚举值不正确?

前端之家收集整理的这篇文章主要介绍了c – 强制枚举值不正确?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我在C的枚举中遇到了一些不寻常的(至少对我而言)行为.我在Visual Studio 2008和g版本4.4.3中尝试了以下内容
#include <iostream>
using namespace std;

enum testEnum
{
    // no zero enum
    one = 1,two = 2,three = 3
};

int main(int argc,char *argv[])
{
    testEnum e;  // undefined value (may be zero,but thats just luck)
    cout << "Uninitialized enum e = " << e << endl;

    /*
        testEnum e2(0);  // error converting from int to enum
    */

    testEnum e3(testEnum(0)); // forces zero !?!!?!?
    cout << "zero enum e3 = " << e3 << endl;  // prints '0'

    testEnum e4(testEnum(9999)); // forces 9999 ?!?!?!?!
    cout << "9999 enum e4 = " << e4 << endl; // prints '9999'

    return 0;
}

e的未定义值是我所期望的,我理解为什么你不能从int转换为枚举(但你可以转向另一种方式).

我很好奇最后两个枚举(e3和e4)如何被允许编译并获得你想要给它们的任何值.

另外,我发现这个:

testEnum e();

在studio和linux中编译,在linux中进行cout-ing产生’1′,但在工作室中我遇到了一个链接错误

main.obj : error LNK2001: unresolved external symbol "enum testEnum __cdecl e2(void)"

在工作室,我可以这样做:

testEnum e = testEnum();

但是,它的结果是’0’而不是’1′

所以我的主要问题是如何在上面的例子中像e3和e4一样将任何值压缩到枚举的喉咙上.如果这取决于实现是否依赖.

解决方法

枚举保证在其最小定义值和最大定义值之间的范围内保持任何值,并且未指定它如何处理该范围之外的数字.

§7.2/3
…if not explicitly specified,the underlying type of a
scoped enumeration type is int.”

§ 7.2/7
…for an enumeration where emin is the smallest enumerator and emax
is the largest,the values of the enumeration are the values in the
range bmin to bmax,defined as follows: Let K be 1 for a two’s
complement representation and 0 for a one’s complement or
sign-magnitude representation. bmax is the smallest value greater than
or equal to max(|emin| − K,|emax|) and equal to 2M − 1,where M is a
non-negative integer. bmin is zero if emin is non-negative and −(bmax
+ K) otherwise. The size of the smallest bit-field large enough to
hold all the values of the enumeration type is max(M,1) if bmin is
zero and M + 1 otherwise.

§ 7.2/10
An expression of arithmetic or enumeration type can be converted to an
enumeration type explicitly. The value is unchanged if it is in the
range of enumeration values of the enumeration type; otherwise the
resulting enumeration value is unspecified.

另请注意testEnum e();声明一个返回testEnum的函数这是由Most Vexing Parse引起的.不确定为什么GCC决定等于一个(也许它被强制转换为指针 – > bool以某种方式?)testEnum e = testEnum();是一个有效的语句,默认初始化一个testEnum,对于原语(显然是枚举)意味着将它们设置为零.

请注意,这并不意味着枚举可能不会超出其定义的范围;如N4296脚注96所述:

This set of values is used to define promotion and conversion semantics for the enumeration type. It does not preclude an
expression of enumeration type from having a value that falls outside this range.

我还要提一下,在C 03中制作类型安全的枚举并不是特别复杂,只有一些奇怪的技巧. http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Type_Safe_Enum显示了一种方式.

猜你在找的C&C++相关文章