2015-01-22 3 views
3

Я случайно сделал ошибку, используя ключевое слово extern, а затем обнаружил, что компилятор разрешил мою строку кода. Почему разрешена следующая программа? Разве компилятор отключает ключевое слово extern? Он даже не дает предупреждения.Почему компилятор C++ разрешает ключевое слово extern в сочетании с определением?

#include <iostream> 

extern void test() { std::cout << "Hello world!" << std::endl; }; 

int main() 
{ 
    test(); 
} 
+1

Почему, на ваш взгляд, это запрещено? – user657267

+0

Не компилятор (некоторые в любом случае) не добавляет 'extern' по умолчанию? –

+0

C компиляторы также позволяют это (и я склонен предположить, что стандарт также позволяет это). –

ответ

3

Это не является необычным, на самом деле, C++ внутренне делает, что точно такую ​​же вещь, обратите внимание, что 1,4/6 говорит:

шаблоны, классы, функции и объекты в библиотеке есть внешний связь

Шаблоны в библиотеке, очевидно, также имеют определения. И почему бы и нет!

Посмотрите, что 3,1/2 и 3,4/2 (курсив наш) должен сказать:

Декларация является определение, если оно не заявляет функцию без указания тела функции (8.4), [или] она содержит EXTERN спецификатора (7.1.1) или тяги-specification25 (7.5) и ни инициализатор, ни ТелаФункции
[...]
Когда имя имеет внешнее связывание, сущность оно обозначает может можно назвать именами из областей o переводческие единицы или из других областей одной и той же единицы перевода.

Ваше объявление имеет тело функции, поэтому это определение, и это явно, совершенно допустимо. Функция имеет внешнюю связь, что означает, что вы может ссылаться на нее по имени из области в другой единицы перевода, но вы не требуется для этого.

Вам по-прежнему разрешено вызывать его по имени в текущем блоке перевода, и именно это вы делаете.

Обратите внимание, что существует пункт о именах в области пространства имен, поэтому ваше использование ключевого слова extern в любом случае является избыточным.