当前位置:  开发笔记 > 编程语言 > 正文

"控制到达非空函数的结束",在枚举类型上使用完全处理的情况切换

如何解决《"控制到达非空函数的结束",在枚举类型上使用完全处理的情况切换》经验,为你挑选了1个好方法。

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

typedef enum {
    A,
    B
} type_t;

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


相关:检测是否将int转换为枚举结果为非枚举值



1> M.M..:

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

可以定义具有未由其任何枚举​​器定义的值的枚举.

现在,有一系列规则确切地指出哪些其他值可能用于其他类型的枚举.

有两类枚举.第一种是 固定的基础类型,例如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 1766号文件承认C++ 14文本存在缺陷,并将其替换为以下内容:

可以将整数或枚举类型的值显式转换为完整的枚举类型.如果原始值在枚举值(7.2)的范围内,则该值不变.否则,行为未定义.

因此,在你正好有两个普查员与价值的具体情况01,没有其他价值是不可能的,除非该计划已经引发未定义行为,所以警告,可能会被认为是假阳性.


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


注意:关于警告本身:编译器不可能准确地警告控制流是否会到达函数的末尾,因为这需要解决停止问题.

他们倾向于谨慎行事:如果编译器不完全确定,则会发出警告,这意味着存在误报.

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


添加一个`default`标签会让Clang抱怨:`switch中的默认标签覆盖所有枚举值`.有时你不能赢...
据我所知,你回答了第一个双重问题:*为什么这个代码会触发"控制到达非空函数的结束",即使所有可能的type_t值都被处理了?*,但是你没有得到答案第二个:*处理此警告的最佳方法是什么?切换后添加返回-1?*
推荐阅读
个性2402852463
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有