2012-01-27 100 views
1

該代碼給出很多是全球性的常量具有內部範圍,這是默認的靜態在C會產生錯誤++常量和全球

// Foo.cpp 
const int Foo = 99; 

// Main.cpp 
extern const int Foo; 
int main() 
{ 
    cout << Foo << endl; 
    return 0; 
}  

原因。

解決方案是: -

//Foo.h 
    extern const int Foo; 

    // Foo.cpp 
    #include "Foo.h" 
    const int Foo = 99; 

    // Main.cpp 
    #include "Foo.h" 
    int main() 
    { 
     cout << Foo << endl; 
    } 

我常想,EXTERN被用來告訴內存爲indentifer已經在其他文件中的某個地方分配的編譯器。
在上面的代碼中應用相同的邏輯,任何人都可以解釋這裏發生了什麼,或者extern在C++中有不同的含義?
enter link description here
還要考慮這個網頁它毀了我所有的直覺..

回答

7

如果我們要聲明只能在全局常量(不static)? extern如何幫助做到這一點?

A const對象聲明爲extern限定符具有外部鏈接。
因此,如果您想跨多個翻譯單元使用const,請在其中添加extern限定符。

儘管默認情況下全局變量具有外部鏈接,但爲什麼默認情況下const全局鏈接具有內部鏈接?

參考:
C++ 03標準附錄C兼容性C.1.2條款3:基本概念

變化:是顯式聲明的常量,而不是文件範圍的名稱明確地聲明爲extern,具有內部連接,而在C中將具有外部連接

理由:因爲const對象可以用作編譯時間val在C++中,這個特性促使程序員爲每個const提供顯式的初始值。此功能允許用戶將常量對象放在包含在許多編譯單元中的頭文件中。


通過以下簡單的規則避免混亂:

缺省情況下聯動爲常量符號外部對非const符號和靜態的(內部)。

3

在此提醒,使得它清楚我們正在談論:

int const a;   // illegal 
int const a = 42;  // definition, internal linkage 
extern int const a;   // declaration, external linkage 
extern int const a = 42; // definition , external linkage 

注意,如果沒有const,上述前兩個聲明是一個具有外部鏈接都 定義。這只是正交,並不是很直觀,但這是現行規則所說的。

與給予一個const外部連接的問題在於,只能有一個 具有外部鏈接的對象的定義,並且與一個 例外,只有定義可以具有一個初始化。這意味着對於具有外部鏈接的const的 ,只能在一個 翻譯單元中看到實際值(如果 const用於常量表達式,則必需的實際值)。這可能是默認情況下給予const 內部鏈接的動機。

當然,這不會導致模板問題的結束,理論上至少 ;下面的頭有未定義的行爲,如果它是 包括在多於一個翻譯單元:

#include <std::vector> 

int const fixedValue = 42; 
inline void insertFixedValue(std::vector<int>& dest) 
{ 
    dest.push_back(fixedValue); 
} 

的標準說不僅必須內聯函數和模板具有 令牌相同的序列,但是,所有的符號的必須將 綁定到每個翻譯單元中的相同對象,或者存在違反 的一個定義規則。並且由於fixedValue沒有外部連接,因此每個翻譯單元中都有一個唯一的實例。 (有 異常如果符號指const對象有 立即左值到右值轉換。由於 std::vector<int>::push_back然而通過引用接受其參數, 沒有即時左值到右值的轉換,我們得到了一個未定義 行爲)

和當然,任何人只要有一個模板:

template <int& r> ... 

不能實例化它。

內部聯動的原因當然是歷史性的。今天, 編譯器必須能夠支持諸如:

struct X 
{ 
    static int const a = 42; // declaration!!!, external linkage 
}; 

和功能的各種重複定義。這將是 比較瑣碎延長,允許在 聲明初始化在命名空間範圍類變量的規則,給 類似:

int const a;    // illegal 
int const a = 42;   // definition, external linkage 
extern int const a;   // declaration, external linkage 
extern int const a = 42; // declaration, external linkage 

這將恢復正交性(即使它需要額外的輸入) 。它 也將打破幾乎所有現有的代碼。

另一種方法是治療const變量定義 完全一樣的功能模板今天對待:你可以有多個 定義,但它們都必須是相同的。這大概會避免 大部分(如果不是全部的話)代碼破壞。

+0

'extern const a; '不是有效的C++,我不認爲。你需要像'extern const' ** int **'a;'你在第一個突出顯示的塊中有錯誤,但是在最後一個錯誤。 – 2014-08-06 19:25:13

+0

@RobertCrovella今天我認爲它甚至不是有效的C(如果它是有效的,那肯定是不好的做法)。我修復了它。 – 2014-08-07 08:23:09