gpt4 book ai didi

c++ - "control reaches end of non-void function"枚举类型完全处理大小写切换

转载 作者:可可西里 更新时间:2023-11-01 15:14:06 24 4
gpt4 key购买 nike

为什么即使处理了 type_t 的所有可能值,此代码也会触发“控制到达非空函数的结尾”?处理此警告的最佳方法是什么?在切换后添加return -1
(代码测试here)

typedef enum {
A,
B
} type_t;

int useType(type_t x) {
switch (x) {
case A:
return 0;
case B:
return 1;
}
}


相关: Detecting if casting an int to an enum results into a non-enumerated value

最佳答案

一般来说,enum 不是唯一的。例如,有人可以像 useType( (type_t)3 ); 这样调用您的函数。这在 C++14 [dcl.enum]/8 中特别提到:

It is possible to define an enumeration that has values not defined by any of its enumerators.

现在,关于哪些其他类型的枚举可能有哪些其他值,有很多规则。

有两类枚举。第一个是固定的基础类型,例如enum type_t : int,或 enum class type_t。在这些情况下,基础类型的所有值都是有效的枚举数。

第二个是不固定的基础类型,其中包括 C++11 之前的枚举,例如您的枚举。在这种情况下,关于值的规则可以概括为:计算存储枚举所有值所需的最小位数;那么可以用该位数表示的任何数字都是有效值。


所以 - 在您的特定情况下,一个位可以同时包含值 AB,因此 3 不是有效值枚举器。

但如果您的枚举是 A,B,C,那么即使 3 没有具体列出,它也是上述规则的有效值。 (所以我们可以看到几乎所有的枚举都不会排他)。

现在我们需要看看如果有人确实尝试将 3 转换为 type_t 会发生什么情况的规则。转换规则是 C++14 [expr.static.cast]/10,表示产生了一个未指定的值。

然而,CWG issue 1766认识到 C++14 文本有缺陷并已将其替换为以下内容:

A value of integral or enumeration type can be explicitly converted to a complete enumeration type. The value is unchanged if the original value is within the range of the enumeration values (7.2). Otherwise, the behavior is undefined.

因此,在您的特定情况下,恰好有两个具有值 01 的枚举器,除非程序已经触发未定义的行为,否则不可能有其他值,因此警告可以被认为是误报。


要删除警告,请添加一个 default: case 来执行某些操作。为了防御性编程的利益,我还建议,无论如何都有一个默认情况是个好主意。在实践中,它可能用于“包含”未定义的行为:如果有人确实传递了一个无效值,那么您可以彻底抛出或中止。


注意:关于警告本身:编译器不可能准确当且仅当控制流将到达函数末尾时发出警告,因为这需要解决停机问题。

他们往往过于谨慎:编译器会在不确定时发出警告,这意味着存在误报。

因此此警告的存在并不一定表示可执行文件实际上允许进入默认路径。

关于c++ - "control reaches end of non-void function"枚举类型完全处理大小写切换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33607284/

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