**引言:在內核的系統調用函數里,經常遇到函數的參數使用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變量
- (二四)內存分配