转自:http://www.360doc.com/content/12/0416/10/1317564_204045854.shtml
补充一个APUE中的内容,即是restrict修饰符。下面一段引自Sun公司的技术文档:
- restrict
Objects referenced througha
restrict-qualified pointer have aspecial association with that pointer. All references to thatobject must directly or indirectly use the value of this pointer.In the absence of this qualifier, other pointers can alias thisobject. Cacheing the value in an object designated througha restrict-qualified pointer is safe atthe beginning of the block in which the pointer is declared,because no pre-existing aliases may also be used to reference thatobject. The cached value must be restored to the object by the endof the block, where pre-existing aliases again become available.New aliases may be formed within the block, but these must alldepend on the value ofthe restrict-qualified pointer, so thatthey can be identified and adjusted to refer to the cached value.For a restrict-qualified pointer at filescope, the block is the body of each function in the file.
也就是说,比如我有一个内存中的对象,如果用restrict指针修饰,则使用的时候可以把它提到CPU的cache里面进 行处理(不懂硬件,大致意思应该是这样的吧),而不必担心其他指针引用了这个对象,而让它们没有取出正确的值来。最后cache内容还是要写回内存的。
restrict修饰符于1999年通过C标准
这里的restrict让我觉得有些疑惑,一查原来是C99中增加的关键字
那么restrict的意义是什么呢?
One of the new features in the recently approved C standard C99, isthe
概括的说,关键字restrict只用于限定指针;该关键字用于告知编译器,所有修改该指针所指向内容的操作全部都是基于(baseon)该指针的,即不存在其它进行修改操作的途径;这样的后果是帮助编译器进行更好的代码优化,生成更有效率的汇编代码。
举个简单的例子
![APUE(一)](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
![APUE(一)](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
![APUE(一)](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
![APUE(一)](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
![APUE(一)](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
![APUE(一)](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
很显然函数foo()的返回值是0,除非参数x和y的值相同。可以想象,99%的情况下该函数都会返回0而不是1。然而编译起必须保证生成100%正确的代码,因此,编译器不能将原有代码替换成下面的更优版本
![APUE(一)](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
![APUE(一)](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
![APUE(一)](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
![APUE(一)](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
![APUE(一)](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
![APUE(一)](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
啊哈,现在我们有了restrict这个关键字,就可以利用它来帮助编译器安全的进行代码优化了
![APUE(一)](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
![APUE(一)](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
![APUE(一)](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
![APUE(一)](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
![APUE(一)](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
![APUE(一)](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
此时,由于指针 x 是修改 *x的唯一途径,编译起可以确认 “*y=1; ”这行代码不会修改*x的内容,因此可以安全的优化为
![APUE(一)](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
![APUE(一)](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
![APUE(一)](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
![APUE(一)](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
![APUE(一)](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
![APUE(一)](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
转载:http://www.360doc.com/content/12/0416/10/1317564_204045854.shtml
restrict是c99标准引入的,它只可以用于限定和约束指针,并表明指针是访问一个数据对象的唯一且初始的方式.即它告诉编译器,所有修改该指针所指向内存中内容的操作都必须通过该指针来修改,而不能通过其它途径(其它变量或指针)来修改;这样做的好处是,能帮助编译器进行更好的优化代码,生成更有效率的汇编代码.如 int *restrict ptr, ptr 指向的内存单元只能被 ptr访问到,任何同样指向这个内存单元的其他指针都是未定义的,直白点就是无效指针。restrict 的出现是因为 C 语言本身固有的缺陷,C程序员应当主动地规避这个缺陷,而编译器也会很配合地优化你的代码.
例子
考虑下面的例子:int ar[10];
int * restrict restar=(int *)malloc(10*sizeof(int));
int *par=ar;
这里说明restar是访问由malloc()分配的内存的唯一且初始的方式。par就不是了。 那么:
for(n=0;n<10;n++)
{
restar[n]+=5;
ar[n]*=2;
}
因为restar是访问分配的内存的唯一且初始的方式,那么编译器可以将上述对restar的操作进行优化: restar[n]+=8; 而par并不是访问数组ar的唯一方式,因此并不能进行下面的优化: par[n]+=8; 因为在par[n]+=3前,ar[n]*=2进行了改变。使用了关键字restric,编译器就可以放心地进行优化了。 这个关键字据说来源于古老的FORTRAN。有兴趣的看看这个。