c - 返回里面 if 和外面还是 in else?

标签 c optimization if-statement

(C) 如果我有一个包含 if 的函数,如果条件为真,则可以返回某个值,否则返回一个不同的值。使用 else 还是不用麻烦,效率更高还是更低?

即...

int foo (int a) {
    if ((a > 0) && (a < SOME_LIMIT)) {
        b = a //maybe b is some global or something
        return 0;
    } else {
        return 1;
    }
    return 0;
}

或者只是

int foo (int a) {
    if ((a > 0) && (a < SOME_LIMIT)) {
        b = a //maybe b is some global or something
        return 0;
    }
    return 1;
}

假设 GCC,第一个实现会导致编译后的代码与第二个有什么不同吗?

我需要在这里尽可能高效,所以可能减少 else 的分支会很好 - 但从风格上讲,我内心的 OCD 不喜欢看到返回不是 0 或 void 作为最后一条指令功能不太清楚发生了什么。所以如果它无论如何都会被删除,那么我可以把其他的留在那里......

最佳答案

您可以使用 -O3 -S 选项运行 gcc 以生成优化的汇编代码,因此您可以查看(并比较)优化的汇编。我对您的源代码进行了以下更改以使其编译。

文件a.c:

int b;                                                                         

int foo (int a) {             
    if ((a > 0) && (a < 5000)) {  
        b = a;                                                    
        return 0;                                                        
    } else {                                                                   
        return 1;             
    }                                       
    return 0;                          
}

文件b.c:

int b;                                                                         
int foo (int a) {                                                             
    if ((a > 0) && (a < 5000)) {
        b = a;
        return 0;
    }       
    return 1;                                                                  
}

当使用 gcc -O3 -S a.c 编译 a.c 时,会创建文件 a.s。在我的机器上它看起来像这样:

               .file      "a.c"
               .text
               .p2align 4,,15
               .globl     foo
               .type      foo, @function
foo:
.LFB0:
               .cfi_startproc
               movl       4(%esp), %edx
               movl       $1, %eax
               leal       -1(%edx), %ecx
               cmpl       $4998, %ecx
               ja         .L2
               movl       %edx, b
               xorb       %al, %al
.L2:
               rep
               ret
               .cfi_endproc
.LFE0:
               .size      foo, .-foo
               .comm      b,4,4
               .ident     "GCC: (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1"
               .section   .note.GNU-stack,"",@progbits

当使用 gcc -O3 -S b.c 编译 b.c 时,会创建文件 b.s。在我的机器上它看起来像这样:

               .file      "b.c"
               .text
               .p2align 4,,15
               .globl     foo
               .type      foo, @function
foo:
.LFB0:
               .cfi_startproc
               movl       4(%esp), %edx
               movl       $1, %eax
               leal       -1(%edx), %ecx
               cmpl       $4998, %ecx
               ja         .L2
               movl       %edx, b
               xorb       %al, %al
.L2:
               rep
               ret
               .cfi_endproc
.LFE0:
               .size      foo, .-foo
               .comm      b,4,4
               .ident     "GCC: (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1"
               .section   .note.GNU-stack,"",@progbits

请注意,foo: 的组装实现是相同的。因此,在这种情况下,使用此版本的 GCC,以何种方式编写代码并不重要。

关于c - 返回里面 if 和外面还是 in else?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17574391/

相关文章:

java - 登录 Java 的最快方法是什么?

java - Java会优化最大操作吗?

shell - 在 if 语句中使用 grep

c - 父子和 fork 子之间的文件描述符共享

c - 如何使用 ALSA 在缓冲区中录制声音

python - 为什么这段 Haskell 代码这么慢?

if-statement - Golang 模板变量 isset

javascript - jQuery\Javascript - if 语句无法正确计算

c++ - 在 Windows 上检测 free() 之后的使用。 (悬挂指针)

c - 数字后的后缀 L 是否总是与在数字前放置带有 "long"的括号具有相同的效果?