2013-04-30 50 views
0

我有這樣漂亮的小碼:爲什麼編譯器接受含糊變量定義?

//example1 
namespace 
{ 
    int a; 
} 

int a; 

main() 
{ 
    a++; 
    return 0; 
} 

當然,G ++ 4.6.1編譯器不能編譯並輸出一個錯誤:

./temp.cpp: In function ‘int main()’: 
./temp.cpp:10:5: error: reference to ‘a’ is ambiguous 
./temp.cpp:6:5: error: candidates are: int a 
./temp.cpp:2:9: error:     int {anonymous}::a 

沒關係!

但是,當我刪除提及變量「一個」內「」的功能,該程序正在編譯以及:

//example2 
namespace 
{ 
    int a; 
} 

int a; 

main() 
{ 
    return 0; 
} 

1)爲什麼克++編譯器允許的定義變量「a」,在這種情況下,它不允許引用它?

2)它只是g ++編譯器的功能,沒有其他編譯器能夠編譯這樣的代碼(example2)?

3)g ++編譯器是否有相應的標誌來解釋這樣的代碼(example2)爲錯誤?

非常感謝大家!

回答

4

第二個示例是有效的,因爲您仍然可以從該翻譯單元外部訪問全局a

匿名命名空間中的a爲具有內部鏈接的變量提供了一個定義。全局命名空間範圍內的a是具有外部鏈接的變量的定義。您可以在不同的翻譯單元中聲明extern int a;並使用它。

+0

真的! :)我想,在這樣的變量的「a」用法中,它應該放在源代碼的末尾...... – 2013-04-30 13:48:21

+2

它應該放置在最有意義的位置...... – 2013-04-30 13:54:25

1

簡短的回答是「因爲沒有什麼非法的」。這只是在主要使用a這是錯誤的。如果你使用::a它會給你全局的(沒有命名空間)。

而且您可以在名稱空間本身內使用a,例如,我們可以有一個功能:

namespace { 
    int a; 

    int work_with_a() 
    { 
     a += 2; 
     return a; 
    } 

} 


int a; 

int main() 
{ 
    ::a++; 

    int b = work_with_a(); 

    cout << ::a + b; 
} 
+0

如何使用「a」來自匿名命名空間的變量?可能嗎? – 2013-04-30 13:53:42

+1

我編輯過,以澄清你如何在主要使用。 – 2013-04-30 13:56:35

1

只是因爲你不能從main引用a在匿名命名空間並不意味着代碼無效。

匿名命名空間中的a仍可以從匿名命名空間內引用。

全球a可以從任何地方引用(您必須在main中使用::a來消除歧義)。