文章目录
- 逻辑比较之短路逻辑
- 1 基本概念
- 2 简单示例
- 2 编译并查看汇编
- 3 短路逻辑的汇编
- &&逻辑
- ||逻辑
- 4 总结
逻辑比较之短路逻辑
1 基本概念
C++ 中的短路逻辑是指:
&&
(逻辑与):如果左边为false
,右边不会执行;||
(逻辑或):如果左边为true
,右边不会执行。
这些行为在底层汇编中依赖条件跳转指令(如 je
, jne
, jz
, jnz
等)来实现“短路”。
2 简单示例
#include <iostream>bool foo() {std::cout << "foo()" << std::endl;return true;
}bool bar() {std::cout << "bar()" << std::endl;return false;
}int main() {if (bar() && foo()) {std::cout << "true" << std::endl;}return 0;
}
2 编译并查看汇编
g++ -O2 -S test.cpp -o test.s # 生成汇编
# 或
g++ -O2 test.cpp -o test && objdump -d test > test.asm
亦可使用在线工具
3 短路逻辑的汇编
&&逻辑
假设我们关注 bar() && foo()
的短路逻辑,可以看到如下结构:
main:push rbpmov rbp, rspcall bar() ; bar()test al, al ; 测试返回值(al 是返回结果)je .L6 ; 如果 bar() 返回 false,跳过 foo()call foo() ; foo(),只在 bar() 返回 true 时调用test al, alje .L6mov eax, 1jmp .L7
解释:
call _Z3barv
调用bar()
;test al, al
检查返回值;je .Lend
:如果为假,跳过 foo;call _Z3foov
:只有在 bar 为 true 时才执行 foo;- 这体现了
&&
的短路。
||逻辑
if (foo() || bar()) {// ...
}
对应汇编可能是:
main:push rbpmov rbp, rspcall bar()test al, aljne .L6call foo()test al, alje .L7
.L6:mov eax, 1jmp .L8
.L7:mov eax, 0
.L8:test al, alje .L9mov esi, OFFSET FLAT:.LC2mov edi, OFFSET FLAT:std::coutcall std::basic_ostream<char, std::char_traits<char>>& std::operator<<<std::char_traits<char>>(std::basic_ostream<char, std::char_traits<char>>&, char const*)mov esi, OFFSET FLAT:std::basic_ostream<char, std::char_traits<char>>& std::endl<char, std::char_traits<char>>(std::basic_ostream<char, std::char_traits<char>>&)mov rdi, raxcall std::ostream::operator<<(std::ostream& (*)(std::ostream&))
4 总结
&&
在汇编中通过test
+je
等跳转指令判断左操作数是否为假,若为假则跳过右操作数。||
在汇编中通过test
+jne
判断左操作数是否为真,若为真则跳过右操作数。- 所有逻辑短路都依赖于 条件跳转指令实现流程控制,而不是先求值再合并。