Я пытаюсь выяснить, следует ли сообщать отчет об ошибках против Clang, GCC или обоих (я протестировал против соединительной линии Clang и GCC 4.7 0,2: если кто-то может проверить это на стволе НКУ, что было бы полезно):Clang vs. GCC: дружественная глобальная функция с помощью квалифицированных/неквалифицированных имен
в основном, следующий код три строки файл компилируется нормально с -fsyntax-only
, явившейся и C++ 11 режимов:
class A {
friend void f();
};
Обратите внимание, что нет предварительного объявления f()
, но это явно ОК.
Однако Clang (но не НКУ) отклоняет следующее:
class A {
friend void ::f();
};
Ошибка из Clang «нет функции с именем„F“с типом„пустоты()“был найден в указанной области», но я не могу найти оправдания в стандарте для рассмотрения этого случая иначе, чем предыдущий, поэтому я думаю, что это ошибка; Возможно, я ошибаюсь (я читаю из N3242, однако AFAIK - это последний публичный проект до C++ 11).
В следующем примере, однако, отвергается НКУ, а не Clang:
void f() { }
void g()
{
class A {
friend void ::f();
};
}
Ошибка от GCC является «другом декларации„аннулируются е()“в локальном классе без предварительного объявления», который Безразлично» t, похоже, имеет смысл, так как void ::f()
должен ссылаться на f()
в объявлении глобального пространства имен. (Не важно, что friend
-ный глобальной функции с локальным класс бессмыслен, это, кажется, не является незаконным ...)
Наконец, последний пример отвергаются как по Clang и GCC:
void g()
{
class A {
friend void ::f();
};
}
Ошибки «объявление друга» void f() в локальном классе без предварительного объявления »и« no function с именем «f» с типом «void()» не было найдено в указанной области »соответственно. Теперь, есть действительно кажется, какое-то оправдание для отказа от друга декларации ранее необъявленной функции в локальном классе, из 11.4p11, но на самом деле пункт гласит:
Если друг декларация появляется в местном классе (9.8) , а указанное имя является неквалифицированным именем, предварительное объявление просматривается без учета областей, находящихся вне самой внутренней охватывающей неклассовой области. Для функции декларации друга, если нет предварительного объявления, программа плохо формируется ...
Незаконность этого заявления по-видимому, на основе второго предложения в этом пункте, но неясно мне должно ли предложение применяться в случае квалифицированного имени, как это используется в этом случае. (Возможно, может быть, что весь абзац применяется к делу «локального класса», независимо от того, используется ли «неквалифицированное имя», а предложение «и указанное имя является неквалифицированным именем» применяется только к описанному выше описанию в первом предложении, но это похоже на растяжку ... единственная причина, по которой я представляю это как возможность, состоит в том, что оба компилятора отвергают ее.)
В любом случае, так что, насколько я могу судить, все четыре из этих случаи (независимо от того, насколько они разумны или нет) должны быть законными; даже если нет, по крайней мере один из Clang и GCC ошибочен во втором и третьем случаях. Может ли кто-нибудь найти ошибку в моей логике?
Третий и четвертый случаи, по общему признанию, бессмысленны; но я вижу второй случай, нарушающий чей-то действительный и полезный код, поэтому я несколько удивлен, что он никогда не был пойман, если это действительно ошибка.
Ага, спасибо, это имеет смысл тогда. Я думаю ты прав. Узнавайте что-то новое каждый день :) –
Интересно, что GCC в порядке с третьим случаем, если 'f' превращается в шаблон ... который, вероятно, является единственным допустимым вариантом использования для него в любом случае ... но да, третий случай, вероятно, должен быть разрешен для согласованности (если только он специально не запрещен где-то), а второй, вероятно, должен быть отклонен (хотя компилятор может принимать недопустимый код, если захочет, я полагаю). –