Xcode 4.1: Apple LLVM 2.1 ведет себя не так, как LLVM GCC 4.2 и GCC 4.2 - PullRequest
3 голосов
/ 07 октября 2011

По стандарту C ++ 03 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(){ }

Когда я компилирую код C ++ с помощью Xcode 4.1, при выборе разных компиляторов происходит различное поведение. Если выбран 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
}

- Конечная заметка]

1 Ответ

2 голосов
/ 07 октября 2011

Представляется вероятным, учитывая цитату, что это ошибка Clang.

Скорее всего, Clang считает две сущности различными, потому что они были объявлены в разных областях (namespace A и namespace B),и не понимает, что extern "C" подрывает правила области.

Я бы не советовал помещать объявления extern "C" в пространства имен, так как пространства имен для них не имеют значения, и, таким образом, даже если это применимо, это только запутаетразработчики (а иногда и компиляторы: p)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...