在类中声明的枚举的默认值

时间:2016-07-14 12:28:30

标签: c++ enums undefined undefined-behavior

我有一个类,其成员是在此类中声明的枚举:

#include<iostream>

class test
{
public:
    enum TYPE{MAN, WOMAN};

    TYPE type;
};


int main()
{
    test x;
    if(x.type == test::MAN) std::cout<<"MAN"<<std::endl;
    if(x.type == test::WOMAN) std::cout<<"WOMAN"<<std::endl;
    std::cout<<"ok"<<std::endl;
    return 0;
}

I know如果在命名空间范围内声明枚举,则它具有默认值0,并且当它在本地声明时,它没有任何默认值,这会导致未定义的行为。

我的问题是:如果我有一个属于一个类的枚举怎么办?它也是未定义的行为吗?

我测试了上面的代码, x.type 既不是 MAN 也不是 WOMAN 。但是,我只为一个编译器和一个操作系统完成了它。我对更一般的答案感兴趣。我在其他任何地方都没有找到有关此问题的任何信息。

Edit1:可以参考这个不确定的值导致分段错误吗?

Edit2:我知道这不是一个设计良好的类 - 它不是我的,我正在尝试调试它。所以告诉我,我可以默认初始化对象并不能解决我的问题。请把它作为一个理论问题来对待。

3 个答案:

答案 0 :(得分:3)

enum中第一个名称的默认值为0,无论enum的范围如何。

此处test x;中的main自动局部变量没有保证默认值。它具有不确定值。并且使用该值是未定义的行为。

您可以像这样默认初始化它:

test x{};

¹一个微妙的观点是,在顶层,这给出了“值初始化”。 功能

答案 1 :(得分:2)

如果您的对象没有任何构造函数,那么它取决于您创建对象的位置。如果它是全局创建的,那么所有变量都是零初始化的。如果没有,它们没有被正确初始化,从中读取会产生UB。

您可以使用test x{};语法强制对非全局变量进行零初始化。

答案 2 :(得分:2)

首先:对于未定义的行为进行“测试”几乎不会给你正确的答案。

这是undefined behavior,因为您正在读取具有自动存储持续时间的未初始化变量。这样的变量具有不确定值,不得从中读取。每个非静态函数范围变量都有自动存储持续时间。

我认为您将枚举类型的定义(在类定义中发生)与此类型变量的声明混淆(在函数范围内) 。在您的示例中,x是一个具有自动存储持续时间的变量,无论在何处定义TYPE类型。