MSVC2015 bug: using namespace
От: tstalker Украина  
Дата: 02.04.16 18:30
Оценка:
Пусть определён тип T, принадлежащий пространству имён A.
Пусть определена функция f() с параметром типа const T&, принадлежащая пространству имён B.
// Вариант 1

namespace A
{
    struct T;
}

struct A::T
{};

namespace B
{
    void f(const A::T&);
}

void B::f(const A::T&)
{}

Вариант 1
Компиляторы clang, gcc и msvc подтверждают корректность вышеприведенного кода.

Теперь вместо FQN-имени типа T в объявлении и определении функции f() используем соответствующее using-объявление в пространстве имён B:
// Вариант 2

namespace A
{
    struct T;
}

struct A::T
{};

namespace B
{
    using A::T;
    void f(const T&);
}

void B::f(const T&)
{}

Вариант 2
Компиляторы clang, gcc и msvc подтверждают корректность вышеприведенного кода.

Теперь вместо using-объявления имени типа T используем директиву using namespace A в пространстве имён B:
// Вариант 3

namespace A
{
    struct T;
}

struct A::T
{};

namespace B
{
    using namespace A;
    void f(const T&);
}

void B::f(const T&)
{}

Вариант 3
Компиляторы clang и gcc подтверждают корректность вышеприведенного кода.
Компилятор msvc — нет.

Директива using namespace A по определению является холонимом using-объявления любого имени из пространства имён A, что и подтверждают компиляторы clang и gcc.
Следовательно, это не фича MSVC2015, а именно баг.
На свежем Webcompiler данный баг также воспроизводится.

Microsoft уже в курсе.
Просьба поддержать голосованием на их сайте актуальность данного бага.
msvc2015 bug
Re: MSVC2015 bug: using namespace
От: Ops Россия  
Дата: 02.04.16 23:46
Оценка: -1
Здравствуйте, tstalker, Вы писали:

T>Директива using namespace A по определению является холонимом using-объявления любого имени из пространства имён A, что и подтверждают компиляторы clang и gcc.


По определению она является using directive (7.3.4), во втором примере у тебя using declaration

T>Следовательно, это не фича MSVC2015, а именно баг.

T>На свежем Webcompiler данный баг также воспроизводится.

Скорее расширение gcc и шланга, потому что 3.4.2-4

When considering an associated namespace, the lookup is the same as the lookup performed when the associated namespace is used as a qualifier (3.4.3.2) except that:
— Any using-directives in the associated namespace are ignored.


Могу ошибаться, но по-моему тут как раз этот пункт применяется.
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re[2]: MSVC2015 bug: using namespace
От: tstalker Украина  
Дата: 03.04.16 14:32
Оценка: -2 :)
Здравствуйте, Ops, Вы писали:

Ops>По определению она является using directive (7.3.4), во втором примере у тебя using declaration


Спасибо, кэп.
Не хотел разжёвывать очевидные вещи, но приходится:
Вариант 1: FQN.
Вариант 2: using declaration.
Вариант 3: using directive.

Согласно правилам языка C++ справедливо следующее неравенство:

using directive > using declaration > FQN

Именно с целью продемонстрировать справедливость неравенства и были реализованы все 3 варианта на 3 разных компиляторах.
gcc и clang отработали нормально все 3 варианта.
А msvc отработал нормально только 1 и 2 вариант, а на 3 споткнулся.
Вывод однозначен: это баг msvc.

Ops>Скорее расширение gcc и шланга


Бред.
Как раз msvc издавна печально известен более чем вольным трактованием стандарта языка, в чём неоднократно убеждались многие программисты, в том числе и я.
И на КЫВТ, и на других форумах полно такой инфы.
А вот gcc и clang довольно строго относятся к требованиям действующего стандарта и регулярно выпускают новые версии для приведения в соответствие оному.
А если и есть у них какие-то отличные от стандарта расширения, то все они строго документированы.

Ops>потому что 3.4.2-4

...........
Ops>Могу ошибаться, но по-моему тут как раз этот пункт применяется.

Мимо кассы.
Вот вариант 4, не оставляющий никаких сомнений:
// Вариант 4

namespace A
{
    struct T{};
}

namespace B
{
    using namespace A;
    void f(const T&);
}

namespace B
{
    void f(const T&)
    {}
}

Вариант 4
О чудо!
Как и в 3 варианте, по-прежнему есть using directive и нет using declaration.
Но msvc вдруг прекрасно отработал.
Вывод однозначен: баг msvc, обнаруженный в 3 варианте.
Re[3]: MSVC2015 bug: using namespace
От: Ops Россия  
Дата: 03.04.16 14:42
Оценка: +1 -1
Здравствуйте, tstalker, Вы писали:

T>Согласно правилам языка C++ справедливо следующее неравенство:


T>using directive > using declaration > FQN

Шито? Пункт стандарта, пожалуйста.

T>О чудо!

T>Как и в 3 варианте, по-прежнему есть using directive и нет using declaration.
T>Но msvc вдруг прекрасно отработал.
Потому что тут действуют другие правила name lookup, конкретно 3.4.1.2
T>Вывод однозначен: баг msvc, обнаруженный в 3 варианте.
Вывод однозначен: ты вместо стандарта пользуешься какими-то своими домыслами и гадаешь на реализациях компиляторов.
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re[4]: MSVC2015 bug: using namespace
От: tstalker Украина  
Дата: 03.04.16 18:32
Оценка:
Здравствуйте, Ops, Вы писали:

Ops>Вывод однозначен: ты вместо стандарта пользуешься какими-то своими домыслами и гадаешь на реализациях компиляторов.


Жаль, беглым поиском по стандарту не нашёл эквивалентного примера, чтобы припереть тебя к стенке железобетонным аргументом — соответствующей ссылкой на стандарт.
А вообще складывается впечатление, что ты жирный тролль, отвергающий очевидные факты ради лулзов.
Интересно, если проверить мой код на 10 компиляторах, и все 10 подтвердят мою правоту, кроме msvc, тогда ты мне поверишь?
И всё же я попробую припереть тебя к стенке, тролль.
И никакой стандарт тебе не поможет.
Итак, даю мастер-класс укрощения троллей.

1. Допустим, и тип T, и функция f() принадлежат одному пространству имён:
namespace A
{
    using T = int;
    T f(T);
}

A::T A::f(T x)
{
    return x;
}

Вопрос: на каком основании в определении функции f() тип T аргумента не требует fqn?
Ответ: на том, что в определении функции, принадлежащей пространству имён, область видимости данного пространства имён начинается сразу после fqn-имени функции.
Если воспользоваться суффиксным синтаксисом возвращаемого значения функции, то и тип функции f() также не требует fqn:
namespace A
{
    using T = int;
    T f(T);
}

auto A::f(T x) -> T
{
    return x;
}


2. Теперь разнесём тип T и функцию f() по разным пространствам имён:
namespace A
{
    using T = int;
}

namespace B
{
    using namespace A;
    T f(T);
}

// msvc error
auto B::f(T x) -> T
{
    return x;
}

Компиляторы clang и gcc обработали код нормально, msvc — нет.
А почему собственно?
Ещё раз специально для троллей повторяем: в определении функции, принадлежащей пространству имён, область видимости данного пространства имён начинается сразу после fqn-имени функции.
Так может, компилятор msvc не считает тип T принадлежащим обоим пространствам имён A и B?
Проверим:
namespace A
{
    using T = int;
}

namespace B
{
    using namespace A;
    T f(T);
}

// msvc ok
auto B::f(B::T x) -> B::T
{
    return x;
}

Да нет — очень даже считает, иначе как бы работало fqn-имя типа B::T в определении функции f()?
Но тогда возникает закономерный вопрос: почему в законной области видимости пространства имён B компилятор msvc не видит законного имени типа T?
Ещё раз специально для троллей повторяем нудным голосом: в определении функции, принадлежащей пространству имён, область видимости данного пространства имён начинается сразу после fqn-имени функции.
При этом в объявлении функции f() тип T стоит вообще без всякой квалификации!
Что за двойные стандарты у компилятора msvc?

3. Резюме.
3.1. И объявление, и определение функции f() находятся в одной и той же области видимости пространства имён B — ваш К.О.
3.2. Тип T принадлежит обоим пространствам имён A и B (иначе B::T не работало бы).
3.3. Однако в объявлении функции f() компилятор msvc считает тип T принадлежащим пространству имён B, а в определении функции f() — нет.
3.4. Компиляторы clang и gcc таким маразмом не страдают.

4. Вывод.
Вывод однозначен: это баг.

ЗЫ:
Ну давай, тролль, бухти мне про космические корабли процитируй мне соответствующие пункты стандарта...
Отредактировано 03.04.2016 22:13 tstalker . Предыдущая версия .
Re[5]: MSVC2015 bug: using namespace
От: tstalker Украина  
Дата: 07.04.16 06:11
Оценка:
Установил свежий Update 2 на VS2015.
Чуда не произошло: баг остался.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.