【问题标题】:Switch Statement Error **control reaches end of non-void function [-Werror=return-type]**Switch 语句错误 **控制到达非空函数的结尾 [-Werror=return-type]**
【发布时间】:2019-12-08 00:21:10
【问题描述】:

我花了很多时间试图找出它无法正常工作的原因,但我觉得我已经涵盖了我需要的每一个案例。我似乎找不到 “控件到达非无效函数的结尾” 错误。这是我的 switch 语句:

static unsigned int sizeIndex(size_t size) {
    int determine_size = 0;
    switch(determine_size) {
        case 0:
            if (size < 16) {
                return 0;
            }
        case 1:
            if ((size >= 16) && (size < 32)) {
                return 1;
            }
        case 2:
            if ((size >= 32) && (size < 64)) {
                return 2;
            }
        case 3:
            if ((size >= 64) && (size < 128) ) {
                return 3;
            }
        case 4:
            if ((size >= 128) && (size < 256)) {
                return 4;
            }
        case 5:
            if ((size >= 256) && (size < 512)) {
                return 5;
            }
        case 6:
            if ((size >= 512) && (size < 1024)) {
                return 6;
            }
        case 7:
            if ((size >= 1024) && (size < 2048)) {
                return 7;
            }
        case 8:
            if ((size >= 2048) && (size < 4096)) {
                return 8;
            }
        case 9:
            if ((size >= 4096) && (size < 8192)) {
                return 9;
            }
        case 10:
            if ((size >= 8192) && (size < 16384)) {
                return 10;
            }
        case 11: 
            if ((size >= 16384) && (size < 32768)) {
                return 11;
            }
        case 12:
            if (size >= 32768) {
                return 12;
            }
    }
}

任何人都可以看到为什么这会引发“控制到达非空函数 [-Werror=return-type]”错误的原因吗?

谢谢!

【问题讨论】:

  • 这是编译器的一个缺点。无法推断必须执行return 语句之一,即使必须执行。就目前的代码而言,您可以将最后一种情况更改为return 12;,并且行为将是相同的并且编译器会被满足。但是,如果更改开头的int determine_size = 0;,则最终情况的这种更改和不更改的行为将不一样——执行确实可能会通过switch 到函数的末尾……
  • 因为你在函数末尾没有返回语句,以防上面的返回都不匹配。
  • ... 你有计划让这个函数使用不同的determine_size 值吗?如果是这样,当没有执行的测试评估为真时,您希望它返回什么?因为,如果 determine_size 大于 0,对于 size 的值小于第一次测试的阈值,执行将通过 switch,所以你应该有一个 return 语句来覆盖它。

标签: c gcc switch-statement


【解决方案1】:

您的switch 完全没用(因为determine_size 始终是0 而您不使用break),所以您有一系列if 语句,涵盖了size 的整个范围. gcc 似乎没有对此进行检查。甚至以下警告control reaches end of non-void function

if (size >= 4) {
   return 0;
}
if (size < 4) {
   return 1;
}

但是,虽然它给出的警告给出的原因不正确,但该代码中有很多需要警告的地方。

固定:

static unsigned int sizeIndex(size_t size) {
    if      (size <    16) { return  0; }
    else if (size <    32) { return  1; }
    else if (size <    64) { return  2; }
    else if (size <   128) { return  3; }
    else if (size <   256) { return  4; }
    else if (size <   512) { return  5; }
    else if (size <  1024) { return  6; }
    else if (size <  2048) { return  7; }
    else if (size <  4096) { return  8; }
    else if (size <  8192) { return  9; }
    else if (size < 16384) { return 10; }
    else if (size < 32768) { return 11; }
    else                   { return 12; }
}

或者:

static unsigned int sizeIndex(size_t size) {
    unsigned int rv = 0;
    size_t threshold = 16;
    while (size >= threshold && threshold <= 32768) {
       ++rv;
       threshold <<= 1;
    }

    return rv;
}

【讨论】:

    猜你喜欢
    • 2019-12-04
    • 2021-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-21
    • 1970-01-01
    • 1970-01-01
    • 2016-08-13
    相关资源
    最近更新 更多