【问题标题】:Enum variable default value?枚举变量默认值?
【发布时间】:2011-10-14 03:24:43
【问题描述】:

问题很简单:

#include <iostream>

enum SomeEnum {  
    EValue1 = 1,  
    EValue2 = 4
};

int main() {
    SomeEnum enummy;
    std::cout << (int)enummy;
}

输出会是什么?

注意:这不是采访,这是我从以前的开发人员那里继承的代码。这里的流式算子只是举例,实际继承的代码是没有的。

【问题讨论】:

  • 不,我只是在用这样的代码查看继承的代码库,不幸的是......
  • 看答案(-s),我知道这只是对旧规则的另一个确认:“永远不要写原型”。但这是大多数开发人员必须处理的问题——某人的其他原型......
  • @phresnel:当我写“问题很简单”时,我的意思是问题很简单,即容易问,当然答案也不是简单的。
  • 你会得到一个随机数。 (或者说当时堆栈上发生了什么。)但是一些编译器会将 enummy 设置为 0。
  • @QuentinUK:你会得到一个任意号码; “随机”意味着非常具体的东西。但事实上,我相信这种行为是不确定的。

标签: c++ variables enums default-value


【解决方案1】:

该程序有Undefined Behavior。 enummy 的值是不确定的。从概念上讲,您的代码与以下代码之间没有区别:

int main() {
   int i;          //indeterminate value
   std::cout << i; //undefined behavior
};

如果你在命名空间范围内定义了你的变量,它的值将被初始化为 0。

enum SomeEnum {  
    EValue1 = 1,  
    EValue2 = 4,  
};
SomeEnum e; // e is 0
int i;      // i is 0

int main()
{
    cout << e << " " << i; //prints 0 0 
}

e 的值可能与SomeEnum 的任何枚举值不同,请不要感到惊讶。每个枚举类型都有一个基础整数类型(例如intshortlong),并且该枚举类型的对象的可能值集是基础整数类型具有的值集。枚举只是一种方便地命名一些值并创建新类型的方法,但您不会通过枚举器值的集合来限制枚举的值。

更新: 支持我的一些引用:

对 T 类型的对象进行零初始化意味着:
— 如果 T 是标量类型 (3.9),则将对象设置为值 0 (零)转换为 T;

请注意,枚举是标量类型。

对 T 类型的对象进行值初始化意味着:
— 如果 T 是类类型 blah blah
— 如果 T 是非联合类 输入废话
— 如果 T 是数组类型,那么等等等等 — 否则,对象被零初始化

所以,我们进入其他部分。并且命名空间范围的对象是值初始化的

【讨论】:

  • 感谢您的信息。您能否指出 C++ 标准中的特定段落?
  • @Implicit 在答案的最后一部分是这样一个事实,除非用户为枚举定义自己的流式操作符,否则在转换后使用整数类型的默认流式传输。因此,即使e 设置为EValue1,也会打印“1”而不是“EValue1”。不过,您可以创建自己的 std::ostream&amp; operator&lt;&lt;(std::ostream&amp;, SomeEnum) 函数。
  • @Haspemulator:Armen 的解释隐含或明确地涵盖了许多事情:从未初始化的变量中读取、静态的初始化、枚举到整数值的隐式标准转换......恕我直言,期望他这样做是不合理的确定所有这些标准的相关部分,您需要花一些时间阅读 C++ 的基础知识。
  • 事实上,明确提到了这种特殊情况:ISO/IEC 14882:2003(E) 第 4.1 节,左值到右值转换,指出“如果对象未初始化,则程序需要此转换具有未定义的行为。”
  • @ArmenTsirunyan: +1 for Enum 只是一种方便地命名一些值并创建新类型的方法,但您不会通过集合来限制枚举的值枚举数的值。
猜你喜欢
  • 2011-06-25
  • 1970-01-01
  • 2011-10-27
  • 1970-01-01
  • 1970-01-01
  • 2015-08-22
  • 2016-10-10
  • 1970-01-01
相关资源
最近更新 更多