哪些编译器可以检测纯数学函数并优化它们(不告诉你)?
答案 0 :(得分:2)
这样做本身就存在风险,因为语言中有指针并缺乏全局编译功能。分析。因此,如果某个操作被声明为非const,则编译器必须假定它可能有副作用。
示例:
//getx.cpp
int GetX(int input)
{
int* pData = (int*) input;
*pData = 50;
return 0;
}
// gety.cpp
int GetY(int input)
{
return GetX(input + 4);
}
// main.cpp
int main()
{
int arg[] { 0, 4 };
return GetY((int)arg);
}
编译器GetY
时编译器不能告诉GetX
将其参数视为指针,并以非功能性,副作用倾向的方式解除引用和修改数据。该信息仅在链接期间可用,因此您必须重新发明链接的概念,以包含大量代码生成和分析以支持此类功能。
答案 1 :(得分:0)
执行此操作的编译器并非真正(afaik),但在使用插件ReSharper时在Visual Studio中编写C#时,您可以获得编译时提示,指示可以声明某些内容为const
。另一方面,这不属于“没有告诉你”的类别,所以它可能不是你想要的......
答案 2 :(得分:0)
似乎gcc现在做了:在下面的代码上执行“gcc -O2 -S”,并且读取程序集,从test()内部调用foo()被标识为pure并移动到循环之外:
#include <stdio.h>
double __attribute__((noinline)) foo(double x)
{
x = x + 1;
x = x * x;
if (x > 20)
x -= 1;
x -= x * x;
return x;
}
void test(int iters, double x)
{
int i;
for (i = 0; i < iters; ++i) {
printf("%g\n", foo(x));
}
}
这是Fedora 22,gcc 5.1.1,x86_64。我没试过,但是使用-flto,我希望这可以在编译单元中工作。
另外,值得注意的是,今天gcc有命令行选项-Wsuggest-attribute = pure和-Wsuggest-attribute = const。