没有return语句时的Clang优化:是否输入if(false)?

时间:2017-09-08 12:38:40

标签: c++ optimization clang clang++

这是一个小工作代码:

#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

2 个答案:

答案 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",因为没有其他选择。

唯一的另一个选择是您的程序无效。但这是不允许的,所以不可能发生,对吧?至少优化器可能会认为它永远不会发生。