volatile 可能我們用的都比較多也比較常見吧,主要就是告訴編譯器,每次在使用volatile指定的變量時(shí)總是重新去獲取他的值,更簡(jiǎn)單的理解我是這樣的, 為了計(jì)算某個(gè)內(nèi)容地址所存的內(nèi)容會(huì)把他放入CPU寄存器,為了優(yōu)化,下一次就直接從寄存器里取值了 volatile就是為了告訴編譯器,不管什么情況你都要去內(nèi)存里重新獲取他的內(nèi)容!!嘻嘻*^_^* restrict就比較少見了。 restrict說明這個(gè)變量沒有別的指針可以修改,讓編譯器生成只讀內(nèi)存一次的代碼。 'Restrict' Pointers One of the new features in the recently approved C standard C99, is the restrict pointer qualifier. This qualifier can be applied to a data pointer to indicate that, during the scope of that pointer declaration, all data accessed through it will be accessed only through that pointer but not through any other pointer. The 'restrict' keyword thus enables the compiler to perform certain optimizations based on the premise that a given object cannot be changed through another pointer. Now you're probably asking yourself, "doesn't const already guarantee that?" No, it doesn't. The qualifier const ensures that a variable cannot be changed through a particular pointer. However, it's still possible to change the variable through a different pointer. For example:
In this example, both pci and pi point to the same variable, n. You can't change n's value through pci but you can change it using pi. Therefore, the compiler isn't allowed to optimize memory access for *pci by preloading n's value. In this example, the compiler indeed shouldn't preload n because its value changes three times during the execution of f(). However, there are situations in which a variable is accessed only through a single pointer. For example:
The name of the file and its open mode are accessed through unique pointers in fopen(). Therefore, it's possible to preload the values to which the pointers are bound. Indeed, the C99 standard revised the prototype of the function fopen() to the following:
Similar changes were applied to the entire standard C library: printf(), strcpy() and many other functions now take restrict pointers:
C++ doesn't support restrict yet. However, since many C++ compilers are also C compilers, it's likely that this feature will be added to most C++ compilers too. c99中新增加了一個(gè)類型定義,就是restrict。 restrict 的定義是It can be applied only to pointers, and it indicates that a pointer is the sole initial means of accessing a data object. 我不知道確切應(yīng)該怎么翻譯,大意是restrict只對(duì)指針有用,它聲明一個(gè)指針是唯一初始化訪問一個(gè)數(shù)據(jù)對(duì)象。 比如,按照書上的例子,
One of the new features in the recently approved C standard C99, is the restrict pointer qualifier. This qualifier can be applied to a data pointer to indicate that, during the scope of that pointer declaration, all data accessed through it will be accessed only through that pointer but not through any other pointer. The 'restrict' keyword thus enables the compiler to perform certain optimizations based on the premise that a given object cannot be changed through another pointer. Now you're probably asking yourself, "doesn't const already guarantee that?" No, it doesn't. The qualifier const ensures that a variable cannot be changed through a particular pointer. However, it's still possible to change the variable through a different pointer. For example:
In this example, both pci and pi point to the same variable, n. You can't change n's value through pci but you can change it using pi. Therefore, the compiler isn't allowed to optimize memory access for *pci by preloading n's value. In this example, the compiler indeed shouldn't preload n because its value changes three times during the execution of f(). However, there are situations in which a variable is accessed only through a single pointer. For example:
![]() ![]()
The name of the file and its open mode are accessed through unique pointers in fopen(). Therefore, it's possible to preload the values to which the pointers are bound. Indeed, the C99 standard revised the prototype of the function fopen() to the following:
Similar changes were applied to the entire standard C library: printf(), strcpy() and many other functions now take restrict pointers:
所以,在沒有restrict的時(shí)候,編譯器需要考慮上面的出錯(cuò)情況,而無(wú)法優(yōu)化程序。 restrict也可以用在函數(shù)的指針參數(shù)前面,它表示在函數(shù)里沒有其他標(biāo)識(shí)符會(huì)修改指針?biāo)傅臄?shù)據(jù)塊,編譯器可以優(yōu)化函數(shù)。
在C99中新增了類型修飾符(qualifier) restrict 在網(wǎng)上找來(lái)找去,看到介紹它的不多,就把看到的一些介紹做個(gè)總結(jié)。 傳說中下面是是書中的原話,到底是什么書卻沒人說: ========================8<==================================== restrict這種修飾符只適用于指針. 由restrict修飾的指針是最初唯一對(duì)指針?biāo)赶虻膶?duì)象進(jìn)行存取的辦法, 僅當(dāng)?shù)诙€(gè)指針基于第一個(gè)時(shí),才能對(duì)對(duì)象進(jìn)行存取. 因此,對(duì)對(duì)象的存取都限定于基于有restrict修飾的指針表達(dá)式中. 由restrict修飾的指針主要被用做函數(shù)指針,或者指向由malloc()分配的內(nèi)存變量. restrict數(shù)據(jù)類型不改變程序的語(yǔ)義. =======================8<======================================= 感覺說的有的亂,可能是我的理解能力不夠吧。然后在CSDN看到了這個(gè): ========================8<==================================== restrict是C99版新增加的關(guān)鍵字! 如下: C99 中新增加了 restrict 修飾的指針: 由 restrict 修飾的指針是最初唯一對(duì)指針?biāo)赶虻膶?duì)象進(jìn)行存取的方法,僅當(dāng)?shù)诙€(gè)指針基于第一個(gè)時(shí),才能對(duì)對(duì)象進(jìn)行存取。對(duì)對(duì)象的存取都限定于基于由 restrict 修飾的指針表達(dá)式中。 由 restrict 修飾的指針主要用于函數(shù)形參,或指向由 malloc() 分配的內(nèi)存空間。restrict 數(shù)據(jù)類型不改變程序的語(yǔ)義。 編譯器能通過作出 restrict 修飾的指針是存取對(duì)象的唯一方法的假設(shè),更好地優(yōu)化某些類型的例程。 [典型例子] memcpy() 在 C99 中,restrict 可明確用于 memcpy() 的原型,而在 C89 中必須進(jìn)行解釋。 void *memcpy (void *restrict str1, const void *restrict str2, size_t size); /* 通過使用 restrict 修飾 str1 和 str2 來(lái)保證它們指向不重疊的對(duì)象 */ =======================8<======================================= 很多人說這個(gè)關(guān)鍵字主要是用來(lái)加強(qiáng)編譯器優(yōu)化的,理由也很簡(jiǎn)單:“由restrict修飾的指針是最初唯一對(duì)指針?biāo)赶虻膶?duì)象進(jìn)行存取的辦法,僅當(dāng)?shù)诙€(gè)指針基于第一個(gè)時(shí),才能對(duì)對(duì)象進(jìn)行存取.”這樣下面的代碼就可以被很好的優(yōu)化, ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]()
這意味著這些拷貝循環(huán)能夠“并行”(in parallel),由于 例如 aa != b 但還是喜歡下面的例子,從它可以看出restrict不僅僅可以被用來(lái)加強(qiáng)編譯器的優(yōu)化,還是解決我們代碼中存在的隱患。 =====================8<================================ 'Restrict' Pointers One of the new features in the recently approved C standard C99, is the restrict pointer qualifier. This qualifier can be applied to a data pointer to indicate that, during the scope of that pointer declaration, all data accessed through it will be accessed only through that pointer but not through any other pointer. The 'restrict' keyword thus enables the compiler to perform certain optimizations based on the premise that a given object cannot be changed through another pointer. Now you're probably asking yourself, "doesn't const already guarantee that?" No, it doesn't. The qualifier const ensures that a variable cannot be changed through a particular pointer. However, it's still possible to change the variable through a different pointer. For example: void f (const int* pci, int *pi;); // is *pci immutable? In this example, both pci and pi point to the same variable, n. You can't change n's value through pci but you can change it using pi. Therefore, the compiler isn't allowed to optimize memory access for *pci by preloading n's value. In this example, the compiler indeed shouldn't preload n because its value changes three times during the execution of f(). However, there are situations in which a variable is accessed only through a single pointer. For example: The name of the file and its open mode are accessed through unique pointers in fopen(). Therefore, it's possible to preload the values to which the pointers are bound. Indeed, the C99 standard revised the prototype of the function fopen() to the following: =====================8<================================ 上面的例子簡(jiǎn)單來(lái)說就是被const修飾的指針指向的內(nèi)容真的是不變的嗎?在某些情況下顯然不是,如第一段代碼 void f (const int* pci, int *pi ) // is *pci immutable? pci和pi指向的都是n,雖然pci被const修飾,但pci指向的內(nèi)容卻在函數(shù)中被改變了,當(dāng)用restrict修飾符之后 void f ( const int * restrict pci , int * restrict pi ),問題解決了:一旦我們?cè)儆腥纾篺 ( &n , &n ) 的調(diào)用,編譯器將給出錯(cuò)誤提示,這是由于一個(gè)地址可以通過兩個(gè)指針來(lái)訪問。 restrict同樣可以用于數(shù)組的聲明: If you specify type qualifiers such as void foo(int * restrict a);, the C compiler expresses it with array syntax void foo(int a[restrict]); which is essentially the same as declaring a restricted pointer. 寫 了這么多,總結(jié)一下,其實(shí)restrict同const或valiate一樣是一個(gè)修飾符而已,告訴編譯器被restrict修飾的指針?biāo)赶虻膶?duì)象,只 能通過這個(gè)指針或基于這個(gè)指針的其他指針進(jìn)行操作,即限制訪問用restrict限制的指針指向的對(duì)象只能通過這個(gè)指針訪問,這對(duì)編譯器的優(yōu)化很有好處。 但要注意:restrict是C99中新增的關(guān)鍵字,在C89和C++中都不支持,在gcc中可以通過—std=c99來(lái)得到對(duì)它的支持。 |
聯(lián)系客服