int a = 5;
int b = 6;
int c;
Run Code Online (Sandbox Code Playgroud)
第一份声明:
c = a > b ? 1 : 0;
Run Code Online (Sandbox Code Playgroud)
第二声明:
c = (a > b);
Run Code Online (Sandbox Code Playgroud)
上面两个有什么区别?
在普通的编译器上绝对没有区别(除了第一个有更多的击键,第二个有不必要的括号(...)).在一些非常糟糕的优化编译器上,一种形式或另一种形式可能会更慢.
来自的真实结果x > y表示为,1而false表示为0.引用ISO/IEC 9899:201x委员会草案2011年4月12日N1570:
每个操作的
<(小于),>(大于),<=(小于或等于),和>=(大于或等于)应得到1如果指定的关系为真并且0如果它是假的.)结果有类型int.
而且a ? b : c是,如果表达式a的计算结果为真给人的值b,否则c.
因此,结果2是相同的.实际上,如果您编译此代码并反汇编它,您会注意到编译后的代码可能也不同:
int test1(int a, int b) {
return a > b;
}
int test2(int a, int b){
return a > b ? 1 : 0;
}
Run Code Online (Sandbox Code Playgroud)
在GCC 4.7.2,x86-64上编译,调试on(-g) - 这应该确保尽可能地禁用所有优化 - 然后反汇编objdump -d foo.o:
0000000000000000 <test1>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 89 7d fc mov %edi,-0x4(%rbp)
7: 89 75 f8 mov %esi,-0x8(%rbp)
a: 8b 45 fc mov -0x4(%rbp),%eax
d: 3b 45 f8 cmp -0x8(%rbp),%eax
10: 0f 9f c0 setg %al
13: 0f b6 c0 movzbl %al,%eax
16: 5d pop %rbp
17: c3 retq
0000000000000018 <test2>:
18: 55 push %rbp
19: 48 89 e5 mov %rsp,%rbp
1c: 89 7d fc mov %edi,-0x4(%rbp)
1f: 89 75 f8 mov %esi,-0x8(%rbp)
22: 8b 45 fc mov -0x4(%rbp),%eax
25: 3b 45 f8 cmp -0x8(%rbp),%eax
28: 0f 9f c0 setg %al
2b: 0f b6 c0 movzbl %al,%eax
2e: 5d pop %rbp
2f: c3 retq
Run Code Online (Sandbox Code Playgroud)
您可以看到2个函数的代码完全相同; 你不能推断哪一个编译到哪一个.表达式分为3行:
d: 3b 45 f8 cmp -0x8(%rbp),%eax
10: 0f 9f c0 setg %al
13: 0f b6 c0 movzbl %al,%eax
Run Code Online (Sandbox Code Playgroud)
第一个比较b,以a和设置适当的处理器标志.al如果结果为"更大",则第二个设置(寄存器eax/rax的最低字节)为1(注意比较在上面反转!),否则为0; 第三个,movzbl将一个字节零扩展为32位整数,因为我们在int这里返回.
| 归档时间: |
|
| 查看次数: |
118 次 |
| 最近记录: |