Это похожий злополучный вопрос
получил комментарии и короткие ответы, прежде чем он был закрыт, о том, что: Потому что это
как определяется язык. Здесь я прошу доказательства в рамках
Стандарт C ++, что он так определен.
gcc 4.8.1 и clang 3.3, с параметрами диагностики по умолчанию или более строгими,
давать ошибки для дополнительная квалификация или же явная квалификация на
код такой как:
struct x
{
int x::i; // Error: gcc/clang: "extra"};
int ::y; // Error: gcc: "explicit", clang: "extra"
gcc диагностирует такие ошибки начиная с версии 4.1. Но популярные компиляторы не
единодушно об этих ошибках. MSVC ++ 2012 (ноябрьская ОСАГО)
выдает ошибку при int ::y;
но даже с /Wall
не дает никакой диагностики вообще
int x::i;
— тот случай, который поднимал злополучный спрашивающий —
и это различие предполагает обсуждение авторами компилятора MS.
Как эти ошибки гарантированы Стандартом, если они есть? Ссылки на C ++ 11
Стандарт будет достаточно.
Ответ может быть «Они следуют из грамматики». В таком случае,
пожалуйста, попробуйте показать, как они следуют из грамматики и не стесняйтесь использовать
Грамматические классификации Стандарта. У меня есть копия, и я ее перечитал
чтобы понять объяснение.
Полное имя в C ++ всегда должно ссылаться на ранее объявленное имя. Это указано в пунктах 8.3 и 3.4.3.2.
Вы не можете сначала объявить переменную или член, используя полное имя — это приведет к ошибке компилятора «не удается определить идентификатор». Такие классификаторы предназначены для повторного объявления. Отсюда требование, чтобы эти имена находили ранее объявленные объекты.
Это ошибка в компиляторе Microsoft, позволяющая x::i
в рамках определения struct x
, Существует несколько таких ошибок во внешнем интерфейсе MSVC, о которых было сообщено в Microsoft, но они закрываются без исправления (см. Аналогичную, но другую ошибку, сообщенную здесь: https://connect.microsoft.com/VisualStudio/feedback/details/783433/c-compiler-accepts-explicit-constructor-call#details а также https://connect.microsoft.com/VisualStudio/feedback/details/794504/keyword-struct-before-constructor-name).
Причина, по которой он неверен, заключается в том, что вы оба пытаетесь объявить переменную int i
и предоставить область, используя x::i
, Область действия переменной определяется где оно объявляется, поэтому попытка объявить что-либо с помощью спецификации области действия пытается объявить это где-то еще, что недопустимо.