首頁(yè) > 專(zhuān)家說(shuō)

restrict volatile求這兩個(gè)關(guān)鍵字的用法。另外還希望能有簡(jiǎn)單程序解釋下。

來(lái)源:新能源網(wǎng)
時(shí)間:2024-08-17 13:15:57
熱度:

restrict volatile求這兩個(gè)關(guān)鍵字的用法。另外還希望能有簡(jiǎn)單程序解釋下。【專(zhuān)家解說(shuō)】:register 使用修飾符register聲明的變量屬于寄存器存儲(chǔ)類(lèi)

【專(zhuān)家解說(shuō)】:

register

     使用修飾符register聲明的變量屬于寄存器存儲(chǔ)類(lèi)型。該類(lèi)型與自動(dòng)存儲(chǔ)類(lèi)型相似,具有自動(dòng)存儲(chǔ)時(shí)期、代碼塊作用域和內(nèi)連接。聲明為register僅僅是一個(gè)請(qǐng)求,因此該變量仍然可能是普通的自動(dòng)變量。無(wú)論哪種情況,用register修飾的變量都無(wú)法獲取地址。如果沒(méi)有被初始化,它的值是未定的。

volatile
     volatile告訴編譯器該被變量除了可被程序修改外,還可能被其他代理、線程修改。因此,當(dāng)使用volatile 聲明的變量的值的時(shí)候,系統(tǒng)總是重新從它所在的內(nèi)存讀取數(shù)據(jù),而不使用寄存器中的緩存的值。比如,

val1=x;
val2=x;

如果沒(méi)有聲明volatile,系統(tǒng)在給val2賦值的時(shí)候可能直接從寄存器讀取x,而不是從內(nèi)存的初始位置讀取。那么在兩次賦值之間,x完全有可能被被某些編譯器未知的因素更改(比如:操作系統(tǒng)、硬件或者其它線程等)。如果聲明為volatile,編譯器將不使用緩存,而是每次都從內(nèi)存重新讀取x。


restrict

     restrict是c99引入的,它只可以用于限定指針,并表明指針是訪問(wèn)一個(gè)數(shù)據(jù)對(duì)象的唯一且初始的方式,考慮下面的例子:

view sourceprint?1int ar[10];2int * restrict restar=(int *)malloc(10*sizeof(int));3int *par=ar;

這里說(shuō)明restar是訪問(wèn)由malloc()分配的內(nèi)存的唯一且初始的方式。par就不是了。那么:

view sourceprint?1for(n=0;n<10;n++)2{3   par[n]+=5;4   restar[n]+=5;5   ar[n]*=2;6   par[n]+=3;7   restar[n]+=3;8}

因?yàn)閞estar是訪問(wèn)分配的內(nèi)存的唯一且初始的方式,那么編譯器可以將上述對(duì)restar的操作進(jìn)行優(yōu)化:restar[n]+=8;。而par并不是訪問(wèn)數(shù)組ar的唯一方式,因此并不能進(jìn)行下面的優(yōu)化:par[n]+=8;。因?yàn)樵趐ar[n]+=3前,ar[n]*=2進(jìn)行了改變。使用了關(guān)鍵字restric,編譯器就可以放心地進(jìn)行優(yōu)化了。這個(gè)關(guān)鍵字據(jù)說(shuō)來(lái)源于古老的FORTRAN。

總結(jié)

     兩個(gè)關(guān)鍵字:volatile和restrict,兩者都是為了方便編譯器的優(yōu)化。