В языке C различают объявление (declaration) и определение (definition).
Примеры:
// Объявление (extern) extern int global_var; int func(int); // Определение int global_var = 42; int func(int x) { return x * 2; }
В многомодульном проекте объявление размещают в заголовочных файлах, чтобы модули "знали друг о друге", а определения — только в одном исходном файле, чтобы не было конфликтов при компоновке.
Могут ли быть несколько одинаковых определений одной и той же переменной (например, int flag = 0;) в разных исходных файлах, если они подключают один и тот же заголовочный файл?
Ответ: Нет! Заголовочный файл должен содержать только объявление extern int flag;, а определение переменной должно быть только в одном исходном файле (int flag = 0;). Несоблюдение приведет к ошибке компоновки о множественном определении.
История
В крупном проекте “разделили” глобальные переменные в заголовочных файлах как
int counter = 0;. Подключали этот заголовок по include, чем вызывали дублирование определения. Итог: ошибка компоновщика при сборке CI/CD — “multiple definition of counter”.
История
В библиотеке функций сделали прототипы функций без спецификации типов, что компилятор тормознул как устаревшее объявление, а затем дал ошибкун при несовпадении сигнатур функций между модулями.
История
На этапе тестирования выяснилось, что часть переменных не инициализируется, так как были объявлены только как
extern, но ни в одном из модулей инициализации не было. Это привело к чтению мусора и трудноуловимым багам на embedded-платформе.