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)
编译器优化不允许改变程序的可观察行为。
Run Code Online (Sandbox Code Playgroud)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"? }
考虑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没有副作用。如果它不能这样做,bar则foo必须依次调用。或者更确切地说:您无法区分它是否被调用或应用了一些优化,因为可观察的行为不能改变。
请注意,某些优化特别允许更改可观察行为,例如复制省略。虽然这与我之前所说的并不完全相反,因为 C++ 标准指定了什么是允许的,什么是不允许的,并且优化可能不会偏离这一点。