2014-02-10 56 views
0

GCC docs常量GCC功能属性和全局常量变量

许多功能不检查任何值,除了他们的论点,并 除了有返回值没有影响。基本上这只是 类比上面的纯属性稍微严格一些,因为 函数不允许读取全局内存。

我的问题是全局的const值是否算作全局内存。我认为它确实如此,但是我明确表示标记为不变的值可能会否定可能的优化,这似乎很奇怪。

例如:

int const ConstantModulusValue = 3; 

int foo(int value) { 
    return foo % ConstantModulusValue; 
} 

采用ConstantModulusValue,我的理解,意味着该函数不应该被打上const这又似乎很奇怪我。标记这个const有没有一些危险,我没有看到。?

回答

1

这些属性允许编译器知道在不知道它是如何实现的情况下忽略对函数的调用是安全的。

纯属性基本上说功能结果只取决于函数参数和全局状态;另外,函数本身不会改变全局状态。

如果你调用一个纯函数两次,它保证返回相同的结果;但是,如果您在调用之间改变全局可见状态,则担保不再成立。

const属性更强,即使全局状态发生了变化,函数仍应返回相同的结果;因此在更多情况下优化对const函数的冗余调用是安全的。

如果您可以保证状态不会发生变化,那么读取全局状态不应该成为问题(注意将全局标记为常量并不总能保证这一点)。

作为一个例子,考虑这样的程序:

int foo(int) __attribute__((pure)); 
int bar(int) __attribute__((const)); 
void unknown(); 

int test1(int a) 
{ 
    int x = foo(a); 
    int y = foo(a); 
    return x + y; 
} 

int test2(int a) 
{ 
    int x = bar(a); 
    int y = bar(a); 
    return x + y; 
} 

int test3(int a) 
{ 
    int x = foo(a); 
    unknown(); 
    int y = foo(a); 
    return x + y; 
} 

int test4(int a) 
{ 
    int x = bar(a); 
    unknown(); 
    int y = bar(a); 
    return x + y; 
} 

用gcc 4.8.1编译它和分析组件揭示TEST1()和TEST2()都只有一次调用相应的功能,然后乘以由2结果; test3()做3次调用 - 2次调用foo和1次调用未知; test4()对bar()进行调用,然后调用unknown(),并返回bar()的结果乘以2.

此行为与上面的解释匹配 - unknown()可以改变全局状态,所以编译器不能将额外的调用隐藏到foo(),但可以将额外的调用删除到bar()。