【问题标题】:What to do about wrong "control reaches end of non-void function" gcc warning?错误的“控制到达非无效函数的结尾”gcc警告怎么办?
【发布时间】:2009-01-18 15:51:01
【问题描述】:
$ cat t.cpp
int sign(int i) {
    if(i > 0) return 1;
    if(i == 0) return 0;
    if(i < 0) return -1;
}
$ g++ -c t.cpp -Wall
t.cpp: In function ‘int sign(int)’:
t.cpp:5: warning: control reaches end of non-void function
$

我该怎么办?

停止使用 -Wall 显然是错误的?最后添加一个虚假的返回0?用“else”子句弄乱代码?

【问题讨论】:

    标签: c++ gcc warnings


    【解决方案1】:

    如果您不想添加“else”子句,因为它们会使代码更长,那么也许您想删除最后的“if”并缩短代码:

    int sign(int i) {
        if(i > 0) return 1;
        if(i == 0) return 0;    
        return -1; // i<0
    }
    

    或者,如果您真的在自己计算“符号”,而这并不是对一些较长示例的简化:

    int sign(int i) {
        return (i>0) ? 1 : ((i<0)?-1:0);
    }
    

    【讨论】:

    • 他为什么不能自己计算符号?这不是标准功能。
    • 你是对的,罗布;我撤回我的反对意见。
    【解决方案2】:

    您的sign() 函数效率不高。试试这个

    int sign(int i) {
        return (i > 0) - (i < 0);
    }
    

    来源:Bit Twiddling Hacks

    【讨论】:

    • 作为计算符号的优雅解决方案,是否最好回答有关警告的问题?
    • @romandas:其他 2 个答案已经涵盖了删除警告的解决方案,因此我不再费心提及它们;此外,当使用我的解决方案时,警告也会消失!
    • 代码的效率肯定是编译器的特性,而不是代码。我没有采用这种依赖于布尔值作为整数的奇怪概念的技巧,而是喜欢清楚表达其意图的代码。不要用糟糕的代码修复编译器错误。
    • 就像补充说,如果你真的想要位旋转,那么用实际的符号位来做些什么呢?
    • @John:将整数视为布尔值可能很奇怪,但这是您在使用 C 编程时必须习惯的事情之一;是的,我认为没有分支的单语句解决方案比带有分支的三语句解决方案更有效......
    【解决方案3】:

    在这种情况下,我会寻求解决方案:

    int sign(int i)
    {
        if (i > 0)
            return 1;
        else if (i == 0)
            return 0;    
        else
            return -1; // i<0
    }
    

    也就是说,我将添加两个 else 子句 - 使代码更加对称,而不是因为它对生成的目标代码有任何影响。

    我做了一些实验。我期望使用三元运算符的单行版本两次生成与更长的代码相同的代码。但是,使用 GCC v4.3.2 在 Solaris 10 (SPARC) 上进行的测试表明,三元运算符版本始终比“if”版本小 12-16 个字节。但是,是否存在额外的 else 并没有区别。 (正如我所料,添加寄存器没有任何问题。)已添加我还查看了 Christoph 的解决方案,即“return (i > 0) - (i

           Unoptimized     Optimized (-O5)
     if      166             110
     ?:      150              98
     >-<     122              98
    

    这主要表明测量是个好主意!

    【讨论】:

    • 嗯...O5 是一个虚假的优化级别。 GCC 没有告诉我。讨厌!我想知道我是否还有测试代码?
    • GCC 目前支持 6 个优化级别:-O0(默认,无优化)、-Os(优化大小),然后是-O1-O2-O3。还有-Ofast,我相信目前相当于-O3 -ffast-math。输入任何大于 3 的数字会将优化级别设置为 -O3,因此您使用的是有效的优化设置,与 -O3 相同。
    • 第一个版本可能更快,尽管更大,因为-O3 愿意以大小换取速度。不太可能,但大小并不能说明全部情况。也可能是文件中留下的一些符号导致程序的“更多行”版本更大,因为有几个额外的符号。您可以尝试与-s 链接,看看是否消除了任何差异。
    【解决方案4】:

    else 子句并不“杂乱无章”,它们是一种更明显的表达意图的方式。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-27
      • 1970-01-01
      • 2013-04-02
      • 1970-01-01
      • 2019-08-29
      • 2012-10-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多