假设我的代码具有以下功能:
inline int foo() {
bar();
int y = baz();
return y;
}
并假设 bar()
和 baz()
有副作用。如果我写:
int z = foo();
printf("z is %d\n", z);
那么显然两者都是bar()
和 baz()
必须被执行。但如果我写:foo();
并且不使用返回值,这是调用 baz()
的唯一原因是因为它的副作用。有没有一种方法可以告诉我的编译器(对于 GCC、clang、MSVC、Intel 中的任何一个),例如“您可以忽略
baz()
的副作用,以便决定是否对其进行优化”?或者“为了决定是否优化它,您可能会忽略此指令的副作用”?这个问题是针对 C 和 C++ 提出的,但可能与各种过程语言相关。让我们使用 C++,因为这是我现在最常用的。
笔记:
bar()
, baz()
不在我的控制之下。 foo()
不得更改。当然我可以使用一些代理并申请 baz()
懒洋洋地,如果我愿意的话;或者只是为不使用 y
的情况写一个不同的函数.这不是我要问的。 最佳答案
作为标准 C 和 C++ 的扩展,gcc 和 clang 支持 pure
function attribute它通知编译器该函数没有副作用并且可以删除不需要的调用。如果你用这个属性声明一个函数,编译器会相信你,即使你在撒谎。
#include <iostream>
static int foo() __attribute__((pure));
static int foo() {
std::cout << "I am a side effect!" << std::endl;
return 17;
}
int main() {
foo();
return 0;
}
This prints no output.请注意 clang
将警告您忽略 pure
的返回值功能。(特别是,当你在 C 中做类似的事情时, gcc optimizes out the call with
-O0
,但是 leaves it in with -O2
!)函数的定义不需要在范围内才能工作,即使先前的声明已经在范围内,您也可以重新声明具有此属性的函数。所以它也可以用于库函数。 Example.
当然,对编译器撒谎总是由您自己承担风险,并且可以想象这可能会产生我没有想到的潜在不良影响。如果您愿意仔细检查生成的代码以确保它真的按照您的意愿行事,这可能是一个有用的技巧,但我不会太相信它。
关于c++ - 我可以告诉我的编译器忽略语句或函数的副作用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64177972/