static (na poziomie pliku/modułu):
static, zasięg jest ograniczony do modułu (pliku) kompilowanego.extern:
Ważne: static — do ukrywania implementacji, extern — do powiązań między modułami.
Przykład:
main.c:
static int hidden_var = 5; extern int shared_var; int main() { printf("shared %d", shared_var); }
shared.c:
int shared_var = 10;
Próba użycia hidden_var z innego pliku spowoduje błąd linkera.
Co się stanie, gdy zdefiniujesz zmienną o tej samej nazwie i różnych specyfikatorach static/extern w różnych modułach?
Odpowiedź: Każda zmienna static (np. static int foo; w różnych plikach) to zupełnie niezależny obiekt. Deklaracja extern int foo; szuka jednej współdzielonej zmiennej globalnej o nazwie foo. Nie można mieszać static i extern — spowoduje to błąd linkowania, jeśli w jednym pliku foo jest zdefiniowana jako static, a w innym zadeklarowana jako extern.
Historia W projekcie odkryto powielanie funkcji o tej samej nazwie (bez static) w różnych modułach: linker połączył tylko jedną z nich, druga "zaginęła", co wpłynęło na logikę aplikacji.
Historia W dużym projekcie zdefiniowano zmienną globalną
int counter;w dwóch modułach, za każdym razem bez extern. W rezultacie działanie aplikacji zależało od kolejności linkowania, czasami pojawiały się konflikty symboli.
Historia Moduł używał funkcji z błędnym zasięgiem: została zdefiniowana jako static, a programista próbował ją wywołać z innego źródła — program nie kompilował się bez zmiany modyfikatora na extern (lub bez usunięcia static).