static (на уровне файла/модуля):
static, область видимости ограничена компилируемым модулем (файлом).extern:
Важно: static — для сокрытия реализации, extern — для связывания между модулями.
Пример:
main.c:
static int hidden_var = 5; extern int shared_var; int main() { printf("shared %d", shared_var); }
shared.c:
int shared_var = 10;
Попытка воспользоваться hidden_var из другого файла вызовет ошибку компоновки.
Что произойдёт при определении переменной с одинаковым именем и с разными спецификаторами static/extern в разных модулях?
Ответ: Каждая static-переменная (например, static int foo; в разных файлах) — это совершенно независимый объект. Объявление extern int foo; ищет одну разделяемую глобальную переменную с именем foo. Перемешивать static и extern нельзя — это приведёт к ошибке линковки, если в одном файле foo определена как static, а в другом объявлена extern.
История В проекте обнаружили дублирование одноимённых функций (без static) в разных модулях: линковщик связал только одну из них, другая "потерялась", что повлияло на логику приложения.
История В большом проекте была объявлена глобальная переменная
int counter;в двух модулях, оба раза без extern. В результате поведение приложения зависело от порядка линковки, иногда возникали конфликтные символы.
История Модуль использовал функцию с ошибочной областью видимости: она была определена как static, и разработчик пытался вызвать её из другого исходника — программа не собиралась без смены модификатора на extern (или без удаления static).