我有兩個C源代碼文件;一個文件包含類似下面的聲明:引用另一個C源文件中聲明的volatile變量時,是否需要extern關鍵字?
volatile unsigned char flag=0;
其他C文件包含如參考:
extern unsigned char flag;
這是正確的,安全的,或當引用變量應volatile
關鍵字重複?即
extern volatile unsigned char flag;
我有兩個C源代碼文件;一個文件包含類似下面的聲明:引用另一個C源文件中聲明的volatile變量時,是否需要extern關鍵字?
volatile unsigned char flag=0;
其他C文件包含如參考:
extern unsigned char flag;
這是正確的,安全的,或當引用變量應volatile
關鍵字重複?即
extern volatile unsigned char flag;
不,這是不正確的。
的相同的變量需要使用類型完全相同的所有聲明和volatile
是(不extern
的)類型的一部分
檢查extern
聲明一個好的做法是把它們放在一個頭文件這也包含在定義存在的編譯單元中。然後編譯器會檢查它們的正確性。
Notice what happens if you do that on this example。
prog.c:2:22: error: conflicting type qualifiers for ‘flag’ extern unsigned char flag; ^ prog.c:1:24: note: previous definition of ‘flag’ was here volatile unsigned char flag=0;
我特別避免將不應該應用於volatile變量的優化放到我的答案中,以避免看起來這樣的處理得到保證。如果你想*那*行爲,做一個指針並且拋棄'volatile'。但使用不兼容的定義是未定義的行爲,並可能導致更糟糕的事情,不尊重波動。 –
C99標準一些引號(強調)
6.2.5/25型
任何類型到目前爲止提到的是不合格的類型。每個不合格的 類型具有多個合格版本的類型,對應於const,volatile和 限制限定符中的一個,兩個或全部三個的組合。 一個 類型的合格或不合格的版本是不同的類型
6.2.7/2「兼容型和複合型」
兩種類型的具有兼容的類型,如果其類型是相同的。
...
是指同一對象或函數應具有 兼容所有類型的聲明;否則,的行爲是未定義的。
如果你認爲你的具體的例子了一會兒,怎麼會是隻看到下面的聲明代碼:
extern unsigned char flag;
有什麼想法,flag
需要被視爲volatile
?
此外,與您的問題無關,請記住volatile
通常不足以處理通過多個線程訪問(如果這是您的意圖)。
用於C代碼的術語「一個定義規則」與C++中的相同嗎? –
@Ben:我不認爲C標準文檔使用該術語(而C++標準)。但是,我認爲'一個定義'的概念也適用於C,即使它沒有在標準文檔中明確使用。 –
您使用的是C或C++編譯器嗎?看起來你不應該在這裏使用'C++'標籤。 –
現在,如果您想知道C和C++之間的答案是否會有所不同,那很好。使用兩個標籤**並在您的問題中解釋您關心兩種語言**的方式。 –
編譯器只有* extern *聲明,並生成代碼來訪問變量當然不知道它應該被視爲易失性。鏈接器不會「修復」該代碼,這不是它的工作。你不能忽略它。 –