Пространство имен, использующее объявление (ошибка в GCC / VS2010)? - PullRequest
12 голосов
/ 23 ноября 2010
namespace A{
   int i;
}

int main(){
   using A::i;
   using A::i;
}

VS2010 - отлично компилируется

gcc (ideone) - отлично компилируется

Comeau - выдает ошибку "ComeauTest.c", строка 10: ошибка: "i" уже естьобъявлено в текущей области видимости с использованием A :: i; "

$ 7.3.3 / 8 -" объявление использования - это объявление, и поэтому его можно использовать многократно, где (и только где) несколько объявленийразрешены. "

Пример, приведенный здесь, показывает, что код действительно некорректен.

Итак, это ошибка в GCC и VS2010?

РЕДАКТИРОВАТЬ 2:

Удалите несколько using directives, поскольку это не было связано с запросом в наличии.

Ответы [ 2 ]

11 голосов
/ 24 ноября 2010

Пример, на который вы ссылаетесь , известен как противоречивый . Комитет еще не исправил это.

Итак, это ошибка в GCC и VS2010?

Не думаю, что это ошибка в GCC / VS2010 / Clang или Comeau. Кажется, это ошибка в стандарте C ++. В этих случаях авторы компиляции должны принять решение о том, что является наиболее жизнеспособным. Если вы удалите рассматриваемый пример, то 3.3 / 4 заявит, что пример действителен: «При наличии набора объявлений в одной декларативной области, каждая из которых задает одно и то же безусловное имя, ... все они должны ссылаться на одну и ту же сущность». или все относятся к функциям и шаблонам функций; или ... ".

Возникает вопрос, как обсуждалось в связанном вопросе, на что ссылается 7.3.3 / 8, когда говорится «декларации», по которым комитет не достиг консенсуса. И так, до тех пор 3.3 / 4 применяется для GCC / VS2010 и Clang, в то время как Comeau выбирает другую семантику.

1 голос
/ 23 ноября 2010

Да, вы правы.Это действительно ошибка в g ++, MSVC ++ и Clang.Комо понял это правильно.

Как вы сказали 7.3.3/8 говорит

Объявление использования - это объявление, и поэтому его можно использовать многократно, где (и только там) допускается несколько объявлений

Также приведен следующий фрагмент кода.

void f()
{
    using A::i;
    using A::i;  //error: double declaration
}

Точно так же и ваш код некорректен.

...