C++ 枚举类默认值,无需初始化

sfz*_*sfz 4 c++ gcc c++17

没有初始化的变量的默认值是多少enum class?以下代码打印奇怪的结果。

#include <iostream>
#include <cstdio>

using namespace std;

struct C {
    C() {
        m_a = 1;
    }

    enum class E:bool {
        a = false,
        b = true,
    };

    int m_a;
    E m_e;
};

int main()
{
    C c;
    cin >> c.m_a;
    printf("m_e: %d; compare to C::E::a: %d\n", static_cast<int>(c.m_e), c.m_e == C::E::a);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

使用gcc版本9.4.0构建(Ubuntu 9.4.0-1ubuntu1~20.04.1)

g++ -g -o c c.cpp
# run, input 1 and get the result.
./c
1
m_e: 252; compare to C::E::a: 253
# run c, input 2 and get the result.
./c
2
m_e: 254; compare to C::E::a: 255
Run Code Online (Sandbox Code Playgroud)

Q1: 为什么m_e没有初始化为C::E::a(value false == 0?) 或C::E::b(value true == 1?)

Q2:为什么比较表达式c.m_e == C::E::a返回253/255,而不是false(value 0) 或true(value 1) ?

Ted*_*gmo 5

未初始化的枚举类变量的默认值是多少?

它是不确定的,因为您从未初始化它。因此,读取c.m_e将使您的程序具有未定义的行为,并且该程序可以显示几乎任何值 - 或没有值并崩溃(或更糟)。

改成E m_e;

E m_e{};
Run Code Online (Sandbox Code Playgroud)

并且它将被初始化为零,这false在您的情况下意味着。

注意:如果实际上不是定义的枚举数之一的值,则零初始化enum class可能会导致混乱的结果。0尽管如此,它仍会将enum class的基类型初始化为零。

最好明确一点:

E m_e{E::a};
Run Code Online (Sandbox Code Playgroud)

Q1: 为什么m_e没有初始化为C::E::a(value false == 0?) 或C::E::b(value true == 1?)

因为,它没有初始化,任何东西都可能会显示 - 或者根本不显示。

Q2:为什么比较表达式c.m_e == C::E::a返回253/255,而不返回false(值 0)或true(值 1)?

再次。程序的行为是未定义的

注意:在当前的 MSVC 中,当您执行cin >> c.m_a;并稍后打印 的值时c.m_e,它将显示您输入的值c.m_a。奇怪的?不,这只是未定义行为可能出现的一种方式。