ein*_*ica 4 c++ side-effects compiler-optimization compiler-options elision
假设我的代码具有以下功能:
inline int foo() {
bar();
int y = baz();
return y;
}
Run Code Online (Sandbox Code Playgroud)
并假设bar()和baz()有副作用。
如果我写:
int z = foo();
printf("z is %d\n", z);
Run Code Online (Sandbox Code Playgroud)
那么显然都bar()和baz()必须执行。但如果我写:
foo();
Run Code Online (Sandbox Code Playgroud)
并且不使用返回值,调用的唯一原因baz()是它的副作用。
有没有一种方法可以告诉我的编译器(对于:GCC、clang、MSVC、Intel 中的任何一个),例如“baz()为了决定是否优化它,您可能会忽略它的副作用”?或者“为了决定是否优化它,您可能会忽略此指令的副作用”?
这个问题是针对 C 和 C++ 提出的,但可能与各种过程语言相关。让我们使用 C++,因为这是我现在最常用的。
笔记:
bar(),baz()不在我的控制之下。foo()不得更改。当然baz(),如果我愿意,我可以使用一些代理并懒惰地应用;或者只是为不使用的情况编写一个不同的函数y。这不是我要问的。作为标准 C 和 C++ 的扩展,gcc 和 clang 支持pure function 属性,该属性通知编译器该函数没有副作用并且可以删除不需要的调用。如果你用这个属性声明一个函数,编译器会相信你,即使你在撒谎。
#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;
}
Run Code Online (Sandbox Code Playgroud)
这不打印输出。 请注意,这clang会警告您忽略pure函数的返回值。
(特别是,当您在 C 中执行类似操作时,gcc 会优化调用 with-O0,但将其保留为-O2!)
函数的定义不需要在范围内才能工作,即使先前的声明已经在范围内,您也可以重新声明具有此属性的函数。所以它也可以用于库函数。 例子。
当然,对编译器撒谎总是由您自己承担风险,并且可以想象这可能会产生我没有想到的潜在不良影响。如果您愿意仔细检查生成的代码以确保它真的按照您的意愿行事,这可能是一个有用的技巧,但我不会太相信它。
| 归档时间: |
|
| 查看次数: |
114 次 |
| 最近记录: |