这是一个小工作代码:
#include <iostream>
#include <string>
std::string f(int i) {
if (i == 0)
return "zero";
if (i == 1)
return "one";
}
int main(int argc, char const *argv[]) {
(void)argv;
std::cout << "Passed " << f(argc - 1) << " arguments." << std::endl;
return 0;
}
无需优化进行编译:
$ clang++ ./return_optims_ifs.cpp -o test
./return_optims_ifs.cpp:10:1: warning: control may reach end of non-void function [-Wreturn-type]
}
^
1 warning generated.
$ ./test
Passed zero arguments.
$ ./test a
Passed one arguments.
$ ./test a b
[1] 20447 illegal hardware instruction (core dumped) ./test a b
好的,这显然是预期的。
现在,使用优化编译:
$ clang++ ./return_optims_ifs.cpp -o test -O3
./return_optims_ifs.cpp:10:1: warning: control may reach end of non-void function [-Wreturn-type]
}
^
1 warning generated.
$ ./test
Passed zero arguments.
$ ./test a
Passed one arguments.
$ ./test a b
Passed one arguments.
等等,什么?!
什么样的优化可以假设我希望最后一个if()成为“默认情况”?
我怎样才能禁用此优化,真的看到由于代码错误导致的崩溃,而不是让它们被遮挡?
$ clang --version
clang version 4.0.1 (tags/RELEASE_401/final)
Target: x86_64-unknown-linux-gnu
答案 0 :(得分:1)
编译器优化与架构版本密切相关。
但是我想我仍然可以回答你的问题。
Here你可以看到在线反汇编(使用clang 4.0.1)。
$this_id = 15;
$array = json_decode($response, true);
$ind = array_search($this_id,array_column($array['data']['attribution'], 'source_id'));
if ($ind !== false) {
$found = $array['data']['attribution'][$ind];
//then do this and also use $found
}else{
//then do this instead
}
函数将在以下内容中分解:
f
如您所见,条件分支是指令f[abi:cxx11](int): # @f[abi:cxx11](int)
lea rax, [rdi + 16]
mov qword ptr [rdi], rax
test esi, esi
je .LBB0_1 // <=== JUMP NOT EQUAL
mov byte ptr [rax + 2], 101
mov word ptr [rax], 28271
mov qword ptr [rdi + 8], 3
mov byte ptr [rdi + 19], 0
mov rax, rdi
ret
.LBB0_1:
mov dword ptr [rdi + 16], 1869768058
mov qword ptr [rdi + 8], 4
mov byte ptr [rdi + 20], 0
mov rax, rdi
ret
,如果je .LBB0_1
则跳转。在另一种情况下(i != 0
),函数体将继续。
换句话说,代码将优化为:
i == 0
这就是您可能获得意外结果的原因。您的if (i != 0)
return "one";
else
return "zero";
输入将执行返回"a b"
的案例2 != 0
。
考虑您的代码产生未定义的行为非常重要。这意味着代码的行为可以是任何东西。在另一个编译器/体系结构上,输出结果可能不同。
必须强烈避免使用这种代码。
答案 1 :(得分:1)
什么样的优化可以假设我希望最后的if()成为&#34;默认情况&#34; ?
您的函数必须返回一个值,因为签名是这样的。
从来源我们可以看到选项为return "zero"
和return "one"
。因此,如果它不是"zero"
,则必须 "one"
,因为没有其他选择。
唯一的另一个选择是您的程序无效。但这是不允许的,所以不可能发生,对吧?至少优化器可能会认为它永远不会发生。