首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么switch-case会出现`警告:控制到达非空函数末尾`?

switch-case语句在执行时,需要确保每个case都有对应的逻辑处理,并且每个case的末尾都要有跳出语句(如break)或者返回语句。如果在某个case中没有加上跳出语句,或者在最后一个case中没有加上返回语句,则会出现警告"控制到达非空函数末尾"。

这个警告的出现是为了防止在switch-case语句中遗漏了逻辑或者错误地执行了多个case的逻辑。如果没有加上跳出语句或者返回语句,程序将会继续执行下一个case的逻辑,这可能会导致程序运行的不正确或者出现逻辑错误。

解决这个警告的方法有两种:

  1. 在每个case的逻辑处理完毕后,加上跳出语句(如break)或者返回语句。这样可以确保每个case的逻辑执行完毕后跳出switch-case语句。
  2. 在最后一个case中加上返回语句。这样可以确保最后一个case的逻辑执行完毕后跳出switch-case语句。

对于警告中提到的控制到达非空函数末尾,这是因为在函数中使用了switch-case语句,而函数需要有返回值。如果在最后一个case中没有加上返回语句,那么函数执行完所有的case后没有返回值,这会导致编译器发出警告。

以下是一个示例代码,展示了如何正确使用switch-case语句并解决警告问题:

代码语言:txt
复制
#include <iostream>

int getValue(int num) {
    int result = 0;
    
    switch (num) {
        case 1:
            result = 10;
            break;
        case 2:
            result = 20;
            break;
        case 3:
            result = 30;
            break;
        default:
            result = -1;
            break;
    }
    
    return result;  // 加上返回语句
}

int main() {
    int num = 2;
    int value = getValue(num);
    std::cout << "Value: " << value << std::endl;
    
    return 0;
}

在这个示例代码中,我们定义了一个函数getValue,通过switch-case语句根据传入的参数num返回不同的值。每个case中都加上了跳出语句(break),并在最后一个case中加上了返回语句。这样可以确保代码的逻辑正确,并且不会出现警告"控制到达非空函数末尾"。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

  • 用表驱动代替switch-case

    不知道从什么时候开始,switch-case语句成了代码坏味道的代名词,写代码的时候小心翼翼地避开它,看到别人代码中的switch-case就皱眉头,想想其实大可不必这样,switch-case语句并不是代码坏味道的根源,坏味道来自糟糕的代码(结构)设计,比如过多的switch-case分支,或者多重switch-case嵌套等等,这些都将导致代码可读性下降,如果再加上代码风格较差,代码不对齐,那么坏味道就相当地大了。 简短的switch-case还是继续用吧,但是对于分支太多的长switch-case最好能想办法化解开,那么什么算长什么算短呢?我也不知道,就以在最低分辨率的显示器上能够在一个窗口中完整显示整个switch-case块为判断依据吧。化解长switch-case的方法有很多种,用函数封装或者宏取代case块是治标不治本的方法,使用表驱动通常是治疗这种顽症的有效方法,本文将介绍如何用表驱动方法化解长switch-case。 还是用例子说明问题吧,假设我们要为一个系统编写驱动,系统已经定义好了如下所示的复用接口(MUX): STATUS DriverIoControl(UINT function_no, PVOID para_in, PVOID para_out) 用户层程序通过复用接口调用驱动,功能号就是function_no,驱动程序负责实现具体的DriverIoControl()函数完成相应的功能。这是使用switch-case的典型场景,先看一个使用switch-case的方案: STATUS DriverIoControl(UINT function_no, PVOID para_in, PVOID para_out) { STATUS rc; switch(function_no) { case PROCESSA: rc = ProcessA(para_in,para_out); break; case PROCESSB: rc = ProcessB(para_in,para_out); break; case PROCESSC: rc = ProcessC(para_in,para_out); break; .......... default: rc = UN_SUPPORT; break } return rc; } STATUS ProcessA(PVOID para_in, PVOID para_out) { //一些代码.... } STATUS ProcessB(PVOID para_in, PVOID para_out) { //一些代码.... } STATUS ProcessC(PVOID para_in, PVOID para_out) { //一些代码.... } ................ 这个方案中规中矩,但是如果驱动很复杂,功能很多,那么DriverIoControl函数代码的长度是相当可观的,好像已经闻到坏味道了,呵呵。现在换成使用宏的解决方案: #define DISPATCH_BEGIN(func) switch(func) \ { #define DISPATCH_FUNCTION(func_c, function) case func_c: \ rc = function(para_in,para_out); \ break; #define DISPATCH_END(code) default: \ rc = code; \ } STATUS DriverIoControl(UINT function_no, PVOID para_in, PVOID para_out) { STATUS rc; DISPATCH_BEGIN(function_no) DISPATCH_FUNCTION(PROCESSA,ProcessA) DISPATCH_FUNCTION(PROCESSB,ProcessB) DISPATCH_FUNCTION(PROCESSC,ProcessC) ........................ DISPATCH_END(UN_SUPPORT) return rc; } 嗯,好一点,但好不到哪里去,只是用一行代替多行而已,并不能改变代码随着功能增多线性增长的趋势。罗嗦一下,我不喜欢宏的原因很简单,目前很少有(说实话,是我确实没有见过)调试器支持对宏的展开调试。这很麻烦,当一段掺杂着宏的代码没有达到预期的目的时,你不得不一遍一遍地在心里展开你的宏,以确定它是没有问题的(或者,你根本不能确定,只能假设它没有问

    05
    领券