常量gcc函数属性和全局常量变量

常量gcc函数属性和全局常量变量,gcc,clang,function-attributes,Gcc,Clang,Function Attributes,发件人: 许多函数不检查除参数以外的任何值,并且 除了返回值之外,没有其他效果。基本上这只是 类比上面的纯属性稍微严格一些,因为 函数不允许读取全局内存 我的问题是全局const值是否算作全局内存。我假设是这样,但我显式标记为不变的值可能会否定这里可能的优化,这似乎很奇怪 例如: int const ConstantModulusValue=3; int foo(int值){ 返回foo%ConstantModulusValue; } 根据我的理解,使用ConstantModulusValue

发件人:

许多函数不检查除参数以外的任何值,并且 除了返回值之外,没有其他效果。基本上这只是 类比上面的纯属性稍微严格一些,因为 函数不允许读取全局内存

我的问题是全局
const
值是否算作全局内存。我假设是这样,但我显式标记为不变的值可能会否定这里可能的优化,这似乎很奇怪

例如:

int const ConstantModulusValue=3;
int foo(int值){
返回foo%ConstantModulusValue;
}

根据我的理解,使用
ConstantModulusValue
,意味着此函数不应标记为
const
,这对我来说也很奇怪。将此
常量标记为我看不到的值是否有危险?

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

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

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

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;
}
用GCC4.8.1编译并分析程序集发现test1()和test2()都只调用各自的函数一次,然后将结果乘以2;test3()进行3次调用-2次调用foo,1次调用unknown;test4()先调用bar(),然后调用unknown(),并返回bar()乘以2的结果

此行为与上面的解释相匹配-unknown()可以改变全局状态,因此编译器不能省略对foo()的额外调用,但可以省略对bar()的额外调用