gpt4 book ai didi

c++ - 从未达到打开枚举后的保护代码

转载 作者:IT老高 更新时间:2023-10-28 23:12:01 24 4
gpt4 key购买 nike

我在尝试使用 g++ 4.4.3 编译一些代码时遇到了一个令人困惑的问题。

下面的代码编译得很好,但是当我传递一个“无效”枚举值时,函数没有达到预期的断言,而是返回 1。我发现更奇怪的是,当我取消注释与 E3 枚举值有关的行时,事情开始按预期工作。

switch block 中没有默认条目是设计使然。我们使用 -Wall 选项进行编译以获取未处理枚举值的警告。

enum MyEnum
{
E1,
E2,
//E3
};

int doSomethingWithEnum(MyEnum myEnum)
{
switch (myEnum)
{
case E1: return 1;
case E2: return 2;
//case E3: return 3;
}

assert(!"Should never get here");
return -1;
}

int main(int argc, char **argv)
{
// Should trigger assert, but actually returns 1
int retVal = doSomethingWithEnum(static_cast<MyEnum>(4));
std::cout << "RetVal=" << retVal << std::endl;

return 0;
}

最佳答案

你的 switch 语句将被编译成这个(g++ 4.4.5):

    cmpl    $1, %eax
je .L3
movl $1, %eax
jmp .L4
.L3:
movl $2, %eax
.L4:
leave
ret

可以看出,断言被完全优化掉了,编译器选择与 E2 进行比较并在所有其他情况下返回 1。使用三个枚举值就无法做到这一点。

C++98 标准(静态转换)的第 5.2.9 节给出了允许这样做的原因:

A value of integral or enumeration type can be explicitly converted to an enumeration type. The value is unchanged if the original value is within the range of the enumeration values (7.2). Otherwise, the resulting enumeration value is unspecified.

换句话说,如果您尝试使用非法值,编译器可以自由使用它想要的任何枚举值(在本例中为 E1)。这包括做直观的事情并使用提供的非法值或根据情况使用不同的值,这就是行为根据枚举值的数量而变化的原因。

关于c++ - 从未达到打开枚举后的保护代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8679534/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com