При поиске в спецификации выясняется, что моему компилятору не требуется диагностировать такие ошибки, как
extern int a;
extern float a;
Ранее я думал, что мой компилятор должен это диагностировать, но в спецификации говорится (выделениедобавлено мной)
После всех корректировок типов (во время которых typedefs (7.1.3) заменяются их определениями) типы, указанные во всех объявлениях, ссылающихся на данную переменную или функцию, должны быть идентичнымиза исключением того, что объявления для объекта массива могут указывать типы массивов, которые отличаются наличием или отсутствием привязки основного массива (8.3.4). Нарушение этого правила для идентификации типа не требует диагностики.
И на самом деле я обнаружил случаи, когда компиляторам все равно.Например, GCC и clang принимают следующее
void g() { int f(); }
void h() { float f(); }
Поскольку нарушение правила, для которого не требуется диагностика, означает, что вся программа больше не требует диагностики, это означает, что следующие неправильно сформированныеПрограмма также не требует диагностики (см. 1.4p2).К счастью, и GCC, и Clang их диагностируют.
int f();
float f();
Поведение этого кода во время перевода фактически не определено.Что является причиной этого?Почему спецификация может не требовать отклонения таких случаев и требовать их диагностики?