你今天volatile了嗎? 兌現允諾

2021-04-12 11:49:54 字數 2141 閱讀 6857

*對任意資料型別t,c提供一種標準內建的轉換。這個轉化可以完成從t指標到volatile t指標的轉換,並規定其逆過程即volatile t指標向t指標轉換為非法。

*const指標和volatile指標在轉換規則方面具有相似性。

本篇文章就後乙個觀點繼續深入**。

本人認為const指標的轉換規則與const指標的基本一致,因此只要我們懂得其中的一種規則,那麼另外的一種就可以不攻自破。關鍵就是要懂得其中的共同規律,而不是去死記硬背一些具體應用。1.自相矛盾

t *p;

...void f(t const *qc);

如果呼叫f(p)將p傳入函式,t指標將會轉換成const t指標。整個轉換過程是自動完成的,不必人為地強制轉換t指標。這是一條潛規則。相反,在下面情況下,如果呼叫g(pc),就會產生編譯錯誤:

t const *pc;

...void g(t *q);

因為編譯器拒絕將const t指標轉換成t指標。這也是一條潛規則

讓記住下面的推斷:如果你許諾你使用const是不讓其它程式改變const物件的內容,那麼你自己在後面編寫const相關**時必須要遵守這個許諾。就象一些做官的,表面是一套,背後又是另一套,最後對自己的所做所為不能自圓其說!

下面舉個簡單的例子來說明諾言是怎麼許下,又是怎麼被打破的。

假設有人寫了下面的**:

int const *p;

顯然,他希望通過const阻止任何有意圖去修改const物件的內容的行為,可他又繼續寫下了"挨扁"的**:

*p += 3; /*改變p指向的內容*/

++(*p);

因為,他自己又去修改p指標指向的內容,自相矛盾啊!!!

那讓我們回頭看原先的**:

t const *pc;

...void g(t *q);

當你定義const型別的指標pc,等價於你對編譯器許諾說我決不允許有**直接地或間接地甚至潛在地去修改pc指向的內容。當然,我們的編譯器是「大好人」,肯定會爽快地答應。接著,你又對編譯器許諾說g函式可以修改通過q傳入的任何指標的內容。最後你試著呼叫g(pc)將p通過pc傳入g。這時編譯器肯定看不過去了,一定會這樣地質問你:

你為何將const指標pc傳入可能會改變pc指向內容的g函式呢,你不是決不允許其它**直接地或間接地甚至潛在地去修改pc指向的內容嗎,你現在將pc傳入g函式不是自己打自己嘴巴嗎?嘿嘿,啞口無言了吧!所以,既然做出了許諾,就要堅持到底

繼續下面的**:

t *p;

...void f(t const *qc);

顯然,你許諾編譯器說任何**都可以改變p指向的內容並且你編寫的f函式不會改變通過qc傳入的其它指標指向的內容。編譯器又一次爽快地答應了你。最後你呼叫了f(p)。這次,編譯器只是對你笑笑,心理暗自道:小樣你可別讓我逮到在f函式中呼叫諸如g之類可能會改變p指向的**哦!

2.const vs volatile

前面提過,const指標的轉換規則與const指標的基本一致。不同的是const是你答應編譯器不會編寫可能改變const物件指向的內容的**,而volatile則是編譯器答應你不會對相關**進行優化。

看下面的**:

t volatile *pv;

...void g(t *q);

對比const可以知道,呼叫g(pv)肯定會出現編譯錯誤。因為你跟編譯器說不要間接或直接地甚至潛在地優化pv相關的**,同時你又有跟編譯器說它可以優化通過q傳入的指標的相關**。如果你呼叫g(pv),將不能優化的pv傳入可能會優化pv的g函式,顯然也是危險並且自相矛盾的做法。

再看:t *p;

...void h(t volatile *qv);

對比const可以知道,呼叫h(p)不會有事,因為編譯履行了它的諾言,不在h函式中優化通過qv傳入的任何指標相關的**。

結論:const指標的轉換規則與const指標的基本一致,主要的不同在於誰許下了諾言。對於const,諾言的主體是我們自己,而對於volatile則是編譯器。不論誰許了諾,都必須遵守並兌現它。

你今天volatile了嗎? 慎重使用

根據c c 語法,const可以出現的地方,volatile幾乎也都可以出現。但是,const修飾的物件其值不能改變,而volatile修飾的物件其值可以隨意地改變,也就是說,volatile物件值可能會改變,即使沒有任何 去改變它。在這一點上,最典型的例子就是記憶體對映的裝置暫存器和多執行緒中的共...

今天你笑了嗎?

1 有次等公共汽車時,開過去一輛寶馬,旁邊一位高人對他身邊的人說 看,剛過去那輛就是ibm.2 我一朋友在聯通實習,一天,一老頭走近來,劈頭蓋臉就來句 給我辦張移動卡,好吧?然後我那朋友頭也不抬的就來句 師傅,有人來砸場子 3 同事去見客戶,可能是緊張,一開口便是 劉先生你好,請問你貴姓啊?汗啊 4...

今天,你學習了嗎?

1 對meta的理解 在每個html的頁面中,有這樣一行 charset utf 8 因為每次新建html檔案自動生成這行,一直沒在乎過這個標籤有什麼意義。今天看到這樣的 name viewport content width device width,minimum scale 1.0,maxim...