是否允许优化编译器省略在短路中间接使用的函数调用?

Cha*_*son 4 c c++

C 和 C++ 语言按从左到右的顺序计算||&&,如果左侧确定整个表达式的真值,则必须“短路”右侧。

foo()如果 的结果foo()存储在仅在短路运算符右侧使用的局部变量中,两种语言是否都允许生成的代码不调用?

在下面的示例中,为 生成的代码bar()必须发出对 的调用foo()。编译时baz(),可以一个符合的优化编译器中删除的调用foo(),因为x在编译时是已知的?

int foo(int f);

int bar(int x) {
  int const foo_value = foo(x);
  if (x || foo_value) {
    return 123;
  }
  return 456;
}

int baz(/* assume "void" here for C */) {
  return bar(1); // Can this collapse down to "return 123"?
}
Run Code Online (Sandbox Code Playgroud)

for*_*818 8

编译器优化不允许改变程序的可观察行为。

int foo(int f);

int bar(int x) {
  int const foo_value = foo(x);
  if (x || foo_value) {
    return 123;
  }
  return 456;
}

int baz(/* assume "void" here for C */) {
  return bar(1); // Can this collapse down to "return 123"?
}
Run Code Online (Sandbox Code Playgroud)

考虑foo是(C++):

int foo(int f) {
    std::cout << "hello, foo is called. I am an observable side effect";
    return 42;
}
Run Code Online (Sandbox Code Playgroud)

然后编译器无法优化对fooaway的调用。编译器必须证明foo没有副作用。如果它不能这样做,barfoo必须依次调用。或者更确切地说:您无法区分它是否被调用或应用了一些优化,因为可观察的行为不能改变。

请注意,某些优化特别允许更改可观察行为,例如复制省略。虽然这与我之前所说的并不完全相反,因为 C++ 标准指定了什么是允许的,什么是不允许的,并且优化可能不会偏离这一点。

  • @CharlesNicholson 请考虑,提出错误陈述的问题与包含损坏代码的问题一样正常,而修复是为了找到答案。现在你已经修复了它,我的答案不再同步了。我会修复它,但一般来说最好不要根据您得到的答案来修复问题,因为它会使答案变得无用 (2认同)