extern
jest potrzebny, ponieważ deklaruje, że symbol istnieje i jest określonego typu, i nie przydziela mu miejsca.
Jeśli tak:
int foo;
W pliku nagłówkowym, który jest współdzielony przez kilka plików źródłowych, otrzymasz błąd konsolidatora, ponieważ każde źródło będzie miało swoją własną kopię foo, a linker nie będzie w stanie rozwiązać symbolu.
Zamiast tego, jeśli masz:
extern int foo;
W nagłówku zadeklarowałby symbol, który jest zdefiniowany w innym miejscu w każdym pliku źródłowym.
Jeden (i tylko jeden) plik źródłowy zawierałby
int foo;
co tworzy pojedynczą instancję foo do rozwiązania przez linker.
Nie. #include to polecenie preprocesora, które mówi "umieść cały tekst z tego innego pliku tutaj". Tak więc wszystkie funkcje i zmienne w dołączonym pliku są zdefiniowane w bieżącym pliku.