所以论坛上有人问为什么要使用这个 C 函数(我添加了
const
和 restrict
,以防万一):
void foo(int *const restrict dest, const int *const restrict source) {
*dest = (*source != -1) ? *source : *dest;
}
使用最新的 gcc 和 clang 编译器生成此程序集,并使用
-Os
优化 godbolt 上的大小 :
foo:
mov eax, dword ptr [rsi]
cmp eax, -1
jne .LBB0_2
mov eax, dword ptr [rdi]
.LBB0_2:
mov dword ptr [rdi], eax
ret
这个看似相同的函数却在 godbolt 上少生成一条指令:
void foo(int *const restrict dest, const int *const restrict source) {
if (*source != -1) {
*dest = *source;
}
}
foo:
mov eax, dword ptr [rsi]
cmp eax, -1
je .LBB0_2
mov dword ptr [rdi], eax
.LBB0_2:
ret
也许我遗漏了一些东西,或者也许我低估了编译器优化它的难度。我希望编译器能够检测到
*dest = *dest
不会有任何副作用,因为我没有将其标记为
volatile
,因此允许将三元优化为 if 语句版本。我在 Stack Overflow 上找到了类似问题的其他答案,这些答案通常归结为 GCC 在一种情况下比 Clang 有优势,反之亦然,但奇怪的是,这两种情况对我来说似乎都没有优化这种情况。void foo(int *const restrict dest, const int *const restrict source) {
*dest = (*source != -1) ? *source : *dest;
}
代码片段2:
void foo(int *const restrict dest, const int *const restrict source) {
if (*source != -1) {
*dest = *source;
}
}
代码片段 1 和代码片段 2 实际上在逻辑上并不匹配,这就是汇编代码不同的原因。
' 如果
*source != -1
那么
*dest = *source;
否则*dest = *dest;
'
' 如果
*source != -1
那么
*dest = *source;
'
void foo(int *const restrict dest, const int *const restrict source) {
if (*source != -1) {
*dest = *source;
}
else{
*dest = *dest;
}
}
在 if-else 条件上使用三元:https://www.tutorialspoint.com/ternary-operator-vs-if-else-in-c-cplusplus