Xcode 4.1:Apple LLVM 2.1与LLVM GCC 4.2和GCC 4.2的行为不同

时间:2011-10-07 07:39:30

标签: c++ xcode clang

Per C ++ 03 standard 7.3.3 / 4。由于函数g具有C链接,因此下面的代码是格式良好的。 A :: g()和B :: g()应该引用同一个实体。

namespace A {
    extern "C" void  g();
}

namespace B {
    extern "C" void g();
}

using namespace A;
using namespace B;

int main(){
    g(); // Error (Apple LLVM 2.1): Call to 'g' is ambiguous.

    return 0;
}

extern "C" void  g(){ }

当我使用Xcode 4.1编译C ++代码时,选择不同的编译器时会有不同的行为。如果选择Apple LLVM 2.1,则存在编译错误,例如“调用'g'是不明确的”。如果选择GCC 4.2或LLVM GCC 4.2,它可以成功编译。

这是CLang的缺陷还是我错了?

Apple LLVM 2.1实际上是Clang是前端而LLVM是后端,对吗?

=============================================== ===========================

C ++标准的相应描述是:

如果名称查找在两个不同的名称空间中找到名称的声明,并且声明不声明相同的实体并且不声明函数,则名称的使用是错误的。 [注意:特别是,对象,函数或枚举器的名称不会隐藏在不同命名空间中声明的类或枚举的名称。例如,

namespace A {
    class X { };
    extern "C"   int g();
    extern "C++" int h();
}
namespace B {
    void X(int);
    extern "C"   int g();
    extern "C++" int h();
}

using namespace A;
using namespace B;

void f() {
  X(1); // error: name X found in two namespaces

  g();  // okay: name g refers to the same entity

  h();  // error: name h found in two namespaces
}

-end note]

1 个答案:

答案 0 :(得分:2)

鉴于引用,似乎很可能是一个Clang bug。

最有可能的是,Clang认为这两个实体是不同的,因为它们是在不同的范围(namespace Anamespace B)中声明的,并没有意识到extern "C"颠覆了范围规则。

我建议不要在命名空间中放置extern "C"声明,因为命名空间与那些无关,因此,即使适用,也只会混淆开发人员(有时候编译器:p)