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