为什么编译器接受模糊变量定义?

时间:2013-04-30 13:39:42

标签: c++ g++ ambiguous

我的代码很少:

//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

没关系!

但是当我在“”函数中删除对变量“ a ”的引用时,程序编译得很好:

//example2
namespace 
{
    int a;
}

int a;

main()
{
    return 0;
}

1)为什么g ++编译器允许定义变量“ a ”,在这种情况下它不允许引用它?

2)它只是g ++编译器的功能,没有其他编译器能够编译这样的代码(example2)吗?

3)g ++编译器是否有相应的标志将这些代码(例2)解释为有问题?

非常感谢大家!

3 个答案:

答案 0 :(得分:4)

第二个示例有效,因为您仍然可以从该翻译单元外部访问全局a

匿名命名空间中的a为具有内部链接的变量提供定义。全局命名空间范围内的a是具有外部链接的变量的定义。您可以在其他翻译单元中声明extern int a;并使用它。

答案 1 :(得分:1)

简短的回答是“因为没有任何违法行为”。它只是在main中使用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; 
}

答案 2 :(得分:1)

仅仅因为您无法从a引用匿名命名空间中的main并不意味着代码无效。

仍然可以在匿名命名空间中引用匿名命名空间中的a

可以从任何地方引用全局a(您必须在::a中使用main来消除歧义。