Рассмотрим:
// a.c
static void f(void) {...}
void DoIt(void) {...}
и
// b.c
static void f(void) {...}
void DoIt(void) {...}
Теперь компилятор генерирует объектные файлы из каждого из этих исходных файлов, даже не подозревая о конфликте имен. Подписи void f(void)
скрыты от компоновщика, когда a
и b
связаны с программой, потому что ключевое слово stati c ограничивает их областью файла, но он может видеть две подписи void DoIt(void)
, потому что они обе в глобальном масштабе. Теперь рассмотрим:
// c.c
extern void DoIt(void);
static void f(void)
{
DoIt(void); // Which implementation should be called here?
}
Тот факт, что вы никогда не писали заголовочный файл с именем вашей функции в нем, не означает, что вы или какой-то программист не попытаетесь использовать это имя символа в другом месте. Использование stati c ограничивает загрязнение имени в глобальной области видимости, поэтому, надеюсь, вы не столкнетесь с слишком большим количеством коллизий.
Другая причина, по которой мы скрываем имена символов в области файлов, состоит в том, чтобы затруднить другим программистам использование функций, которые мы не собираемся использовать. Каждый символ, который вы выставляете в глобальном масштабе, - это потенциальный звонок в службу поддержки. Если у вас есть сотни продуктов / разработчиков, которые зависят от ваших внутренних битов, это может затруднить рефакторинг или иное изменение кода. Скрывая его от них в области видимости файла, вы говорите: «Я не поддержу вас, принимая зависимости от этих символов», поэтому, если они go сделают это в любом случае, они не имеют права жаловаться, когда вы их удаляете или изменяете они используются вашим кодом.