Необходимо различать два отдельных понятия: определение функции и объявление символа. «extern» - это модификатор связи, подсказка компилятору о том, где определяется символ, на который ссылаются впоследствии (подсказка «не здесь»).
Если я напишу
extern int i;
в области видимости файла (вне функционального блока) в файле C вы говорите: «переменная может быть определена в другом месте».
extern int f() {return 0;}
является одновременно объявлением функции f и определением функции f. Определение в этом случае переопределяет внешний.
extern int f();
int f() {return 0;}
сначала декларация, затем определение.
Использование extern
неправильно, если вы хотите объявить и одновременно определить переменную области файла. Например,
extern int i = 4;
выдаст ошибку или предупреждение, в зависимости от компилятора.
Использование extern
полезно, если вы явно хотите избежать определения переменной.
Позволь мне объяснить:
Допустим, файл ac содержит:
#include "a.h"
int i = 2;
int f() { i++; return i;}
Файл ах включает в себя:
extern int i;
int f(void);
и файл bc содержит:
#include <stdio.h>
#include "a.h"
int main(void){
printf("%d\n", f());
return 0;
}
Экстерьер в заголовке полезен, потому что он сообщает компилятору на этапе компоновки: «это объявление, а не определение». Если я удалю строку в ac, которая определяет i, выделит для нее место и присвоит ей значение, программа не сможет скомпилироваться с неопределенной ссылкой. Это говорит разработчику, что он ссылался на переменную, но еще не определил ее. Если, с другой стороны, я опускаю ключевое слово "extern" и удаляю int i = 2
строку, программа все равно компилируется - для меня будет задано значение по умолчанию 0.
Переменные области файла неявно определяются со значением по умолчанию, равным 0 или NULL, если вы не присваиваете им значение явно, в отличие от переменных области блока, которые вы объявляете в верхней части функции. Ключевое слово extern избегает этого неявного определения и, следовательно, помогает избежать ошибок.
Для функций в объявлениях функций ключевое слово действительно избыточно. Объявления функций не имеют неявного определения.