【C語言天天練(十九)】restrict關鍵詞
引言:在核心的系統呼叫函式裡,常常遇到函式的引數使用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:
編譯:gcc restrict.c -std=c99#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; }
執行編譯結果:./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;