2013-04-30 47 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来消除歧义)。