【问题标题】:How to fix "error: control reaches end of non-void function"?如何修复“错误:控制到达非无效函数的结尾”?
【发布时间】:2020-02-14 15:39:19
【问题描述】:
int climbStairs(int n ){

    if(n==1){
        return 1;
    }
    if (n>=2){
         return (2+ climbStairs(n-2)+ climbStairs(n-1));
    }
}

如何修复编译器错误?

【问题讨论】:

  • 如果n小于1,函数会返回什么?
  • 别说这不可能发生。当n == 2 时,递归执行climbStairs(0)climbStairs(1)
  • n-123 时会发生什么?
  • 假设 n == 0 在这种情况下你会返回什么?

标签: c


【解决方案1】:

你的编译器没有你聪明。您可能很清楚,函数永远不会在 n 小于 1 的情况下被调用,但编译器不会。就我个人而言,我认为它被称为 n0 用于典型输入。

因此它认为程序控制可以在没有显式返回的情况下到达函数右大括号},如果你使用函数返回值,这正式是未定义的行为,重复一遍,我认为你会的。

编译器向您发出的这个警告提升为错误,因此编译停止。

一些修复:

  1. 用更强的if (n <= 1){阻止递归。

  2. 在右大括号 } 之前使用 assert(false) 或类似方法进行运行时断言。

  3. 关闭将该警告提升为错误,但仍要处理该警告。


@JonathanLeffler 的一些建议

不要关闭 -Werror - 它太有价值了。处理警告。断言(n >= 0);在顶部;如果 (n

【讨论】:

  • Afaics,对于任何n > 1,函数climbstairs(0) 将在某个时候被调用。
  • @Ctx:我同意这一点。
  • 不要关闭-Werror——它太有价值了。处理警告。 assert(n >= 0); 在顶部; if (n <= 1) { return 1; } 也是。断言在调试版本中触发;即使未启用断言,错误的参数值也能合理安全地处理。
  • 避免n < 0问题的另一种方法是使用unsigned而不是int
  • 你的编译器没有你聪明。我想说编译器在这种情况下聪明。它知道您对输入的假设可能是错误的,因为实际上代码最终会在输入超出预期范围的情况下被调用。
【解决方案2】:

除了其他答案之外,这里还有另一个好技巧。

如果您绝对确定自己比编译器了解更多,并且没有什么可返回的,那么将abort(); 作为函数的最后一行。编译器足够聪明,知道abort() 永远不会返回,因为它会导致程序崩溃。这将使警告静音。

请注意,程序崩溃是一件好事。因为在这种情况下,当“不可能的事情”确实发生时,你会遇到崩溃,如果你正在使用它,它会在你的调试器中弹出。

【讨论】:

    猜你喜欢
    • 2017-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-07
    • 1970-01-01
    • 1970-01-01
    • 2022-01-25
    相关资源
    最近更新 更多