以下代码在GCC 4.2下编译时没有任何警告,据我所知,它确实不应该:
#include <fstream>
__attribute__((pure))
double UnpureFunction(double* x) {
x[0] = 42;
return 43;
}
int main () {
double x[] = {0};
double y = UnpureFunction(x);
printf("%.2f %.2f\n", x[0], y);
}
(打印“42.00 43.00”。)
据我了解,pure属性告诉编译器该函数没有外部效果(参见“纯”here部分)。但是UnpureFunction正在修改它的参数。为什么允许这种情况发生?至少,编译器可以自动生成每个参数const。
答案 0 :(得分:10)
据我所知,pure
是你对编译器的承诺,但它不会尝试验证你是不是在撒谎。
即使它强制参数为const
,这些参数也可能存在(例如,对象可能有一个可变成员,当您的代码调用成员函数时,该成员会被修改)。
如果您正在寻找const正确性,请使用const
参数。 pure
和const
属性用于提供可用于优化的提示。
答案 1 :(得分:1)
首先,如果函数转发其参数的const / non-const,那么该函数仍然可以是纯的,稍后一些函数会修改它。也就是说,非const引用并没有规定该函数会特别修改它,而是非const引用授予访问权限,即链中的某些操作将修改状态(即产生副作用)。例如,如果我想编写一个返回ints向量的第一个元素的函数:
int& first(std::vector<int>& v) __attribute__((pure))
{
return *(v.begin());
}
我可以将它声明为纯,即使它可能需要非const引用,因为first()
不会修改向量。相反,它只检索第一个元素(通常不会产生副作用)。稍后的某些操作可能会修改该值。从这个意义上说,它只转发范围的const / non-const。
其次,即使参数是const
,它仍然不能保证没有副作用,因为即使类{{1} class
也可以将字段声明为可修改的},使用关键字const
。
答案 2 :(得分:-2)