[英]External, internal and no linkage or why this does not work?
根據C標准:
在構成整個程序的翻譯單元和庫的集合中,具有外部鏈接的特定標識符的每個聲明表示相同的對象或功能。 在一個翻譯單元內,具有內部鏈接的標識符的每個聲明表示相同的對象或功能。 沒有鏈接的標識符的每個聲明表示唯一的實體。
在我的例子中,我們有三個單獨的聲明,每個標識符具有不同的鏈接。所以為什么這不起作用?
static int a; //a_Internal
int main(void) {
int a; //a_Local
{
extern int a; //a_External
}
return 0;
}
錯誤:
在函數'main'中:第9行:錯誤:變量先前聲明'static'relayclared'extern'
為什么編譯器堅持要重新聲明我而不是嘗試訪問另一個文件中的外部對象?
有效的C ++示例供參考:
static void f();
static int i = 0; // #1
void g() {
extern void f(); // internal linkage
int i; // #2 i has no linkage
{
extern void f(); // internal linkage
extern int i; // #3 external linkage
}
}
Clang和VC似乎都適用於我的C示例; 只有某些版本的GCC(並非所有版本)都會產生上述錯誤。
§6.2.2,7說:
如果在翻譯單元內,同一標識符同時出現內部和外部鏈接,則行為未定義。
所以,你的程序有不確定的行為 。
§6.2.2,4表示
extern int a; //a_External
具有外部鏈接,因為先前聲明在范圍int a; //a_Local
可見int a; //a_Local
int a; //a_Local
沒有鏈接 。 但
static int a; //a_Internal
聲明a
內部鏈接。 因此,根據§6.2.2,7 未定義 。
編譯器給這個錯誤,因為里面a_External
范圍, a_Internal
仍然是可以訪問,從而你重新聲明a_Internal
從static
到extern
在a_External
因為名稱沖突的a
。 可以使用不同的變量名來解決此問題,例如:
static int a1; //a_Internal
int main(void) {
int a2; //a_Local
{
extern int a3; //a_External
}
return 0;
}
C標准說:
在該組翻譯單元中,具有外部鏈接的特定標識符的每個聲明表示相同的實體(對象或功能)。 在一個翻譯單元內,具有內部鏈接的標識符的每個聲明表示相同的實體。
在翻譯單元集中,我們不能有多個具有相同名稱的不同外部實體,因此表示該單個外部實體的每個聲明的類型應該一致。 我們可以在一個翻譯單元中檢查類型是否一致,這是在編譯時完成的。 我們無法在編譯時或鏈接時檢查不同翻譯單元之間的類型是否一致。
對於在范圍內使用存儲類說明符extern聲明的標識符,其中該標識符的先前聲明是可見的,31)如果先前聲明指定內部或外部鏈接,則后面聲明中標識符的鏈接與在先前聲明中指定的聯系。 如果沒有先前聲明可見,或者先前聲明未指定鏈接,則標識符具有外部鏈接。
static int a; //a_Internal
int main(void) {
int a; //No linkage
{
extern int a; //a_External
}
return 0;
}
這里前面的標識符聲明a沒有鏈接,所以extern int a
有外部鏈接。 這意味着我們必須在另一個翻譯單元中定義int。 但是GCC決定用變量先前聲明的static
重新聲明的'extern'錯誤拒絕這個代碼,可能是因為根據C
標准我們有未定義的行為。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.