restrict
允許編譯器優化某部分代碼以更好地支援計算,它隻能用于指針,表明該指針是通路資料對象的唯一且初始的方式。
用于告訴編譯器,對象已經被指針所引用,不能通過除該指針外所有其他直接或間接的方式修改該對象的内容。
#include<stdio.h>
int main()
{
int arr[10];
int *restrict restar=(int *)malloc(10*sizeof(int));
int *par=ar;
for(int n=0;n<10;n++)
{
par[n]+=5;
restar[n]+=5;
arr[n]*=2;
par[n]+=3;
restar[n]+=3;
}
}
因為restar是通路它所指向的資料塊的唯一且初始的方式,編譯器可以把涉及restart的兩條語句替換成下面這條語句,效果相同
restar[n]+=8;
但是把與par相關的兩條語句替換成下面的語句,将導緻計算錯誤
par[n]+=8;
因為for循環在par兩次通路相同的資料之間,用ar改變了該資料的值.在該例中,如果使用了 restrict 關鍵字,編譯器就可以選擇捷徑優化計算
restrict還可用于函數形參中的指針,這意味着編譯器可以假定在函數體内其他
辨別符不會修改該指針指向的資料,而且編譯器可以嘗試對其優化,使其不做别的用途
volatile 類型限定符
告知計算機,代理可以改變該變量的值,通常,它被用于硬體位址及 在其他程式或同時運作的線程中共享資料,例如,一個位址上可能存儲着目前的時鐘時間,無論程式做什麼,位址上的值都随着時間的變化而改變,或者一個位址用于接受另一台計算機傳入的資訊.簡單地說就是防止編譯器對代碼進行優化。 確定本條指令不會因編譯器的優化而省略,且要求每次直接讀值.精确地說就是,優化器在用到這個變量時必須每次都小心地重新讀取這個變量的值,而不是使用儲存在寄存器裡的備份。volatile int locl; //易變型變量,locl 是一個易變的位置說明這變量可能會被意想不到的改變,這樣,編譯器就不會假設這個變量的值了 volatile int *ploc; //指向易變型變量的指針, val1=x; val2=x; 智能的(進行優化的)編譯器會注意到以上代碼使用了兩次x,但并未改變它的值,于是編譯器 把x的值臨時存儲在寄存器中,然後在val2需要使用x時,才從寄存器中(而不是從原始記憶體位置 上)讀取x的值,以節約時間,這個過程被稱為高速緩存。 但是如果一些其他代理在以上兩句語句之間改變了x的值,就不能這樣優化了,如果沒有 volatile 關鍵字,編譯器就不會知道這種事情是否會發生。而現在,如果未使用volatile 關鍵字,編譯 器會假定變量的值在使用過程中不變,然後嘗試優化 volatile const int loc; //程式不能改變的變量,但是可以通過代理改變 const volatile int *ploc;