**引言:在内核的系统调用函数里,经常遇到函数的参数使用restrict限定词限定的情况,下面就对该关键词做个总结。**
1、restrict关键词是C99特性才添加的,因此在编译使用含有该限定词的程序时,一定要在后边添加-std=c99的标志,使得gcc能够支持c99标准。
2、restrict既然是个限定词,那么它限定什么变量呢?它只能限定指针变量!经过它限定的数据对象,表明指针时访问该数据对象的唯一且初始的方式。注意:这里的唯一表明了,由它限定的指针所指向的数据块,只能由该指针访问,不能由除它之外的任何方式访问。初始指的是它必须在初始化的时候声明,不能再以后声明。后面给出例子解释。
3、restrict其实可以看成只有两个读者。一个是编译器,它告诉编译器可以自由地做一些有关优化的假定。另一个读者是用户,它告诉用户仅适用满足restrict要求的参数。比如,下列两个函数声明:
void *memcpy(void *restrict s1, const void *restrict s2, size_t n);
void *memmove(void *s1, const void *s2, size_t n);
上面两个函数都是从位置s2把n个字节复制到位置s1。函数memcpy()要求两个位置之间不重叠,但memmove()没有这个要求。把s1和s2声明为restrict意味着每个指针都是相应数据的唯一访问方式,因此他们不能访问同一数据块。这满足了不能有重叠的要求。
**程序示例restrict.c:**
~~~
#include <stdio.h>
#include <stdlib.h>
int
main(int argc, char **argv)
{
int n;
int ar[5];
int *restrict restar = (int *)malloc(5 * sizeof(int));/*将该指针声明为了restrict,使得这块内存的数据只能由restar访问,不能由下面的par指针访问*/
int *par = ar;
for(n = 0; n < 5; n++){
par[n] += 5;
restar[n] += 5;
ar[n] *= 2;
par[n] += 3;
restar[n] += 3;
printf("ar[%d] = %d\n", n, restar[n]);
printf("ar[%d] = %d\n", n, ar[n]);
}
return -1;
}
~~~
编译:gcc restrict.c -std=c99
**执行编译结果:./a.out**
**ar[0] = 8
ar[0] = 4851221
ar[1] = 8
ar[1] = 4849653
ar[2] = 8
ar[2] = 269027981
ar[3] = 8
ar[3] = 2147391485
ar[4] = 8
ar[4] = 2614935**
从结果可以看出,通过par指针以及ar所访问的restar指针所指向的数据并没有起任何作用。能够改变所指向内存数据的只是restar[n] += 5;与 resatr[n] += 3;这两条语句。其实编译器会对这两条语句做优化,将它们合并成一条语句:restar[n] += 8;
- 前言
- (四)回调函数
- (一)while(1)死循环与for(;;)死循环的区别
- (二)static关键字
- (三)函数
- (四)可变参数函数
- (五)setjmp和longjmp
- (六)指针
- (七)回调函数
- (八)字符串
- (九)动态内存分配
- (十)结构体
- (十一)深入理解指针
- (十二)命令行参数
- (十三)printf、fprintf、sprintf和snprintf函数
- (十四)const关键字详解
- (十五)字符串输入函数fgets、gets和scanf
- (十六)字符串输出函数puts、fputs和printf
- (十七)字符/字符串输出函数fputc、fputs、putc、putchar和puts
- (十八)字符/字符串输入函数fgetc、fgets、getc、getchar和gets
- (十九)restrict关键词
- (二十)scanf函数详解
- (二一)内联函数
- (二二)位操作
- (二三)errno变量
- (二四)内存分配