В чем разница между обычной глобальной переменной и static-переменной в C++?

«В чем разница между обычной глобальной переменной и static-переменной в C++?» — вопрос из категории C++ Core, который задают на 25% собеседований C/C++ Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Основное отличие — в области видимости (linkage).

  • Обычная глобальная переменная (без static) имеет внешнее связывание (external linkage). Это означает, что она видна во всех единицах трансляции (.cpp файлах) программы, если в них объявить её с помощью extern. Это может приводить к конфликтам имён в больших проектах.
  • Static-глобальная переменная имеет внутреннее связывание (internal linkage). Её область видимости ограничена текущим файлом, в котором она объявлена. Это полезно для скрытия деталей реализации модуля.

Пример:

// File: module.cpp
int global_var = 42;          // Внешнее связывание. Видна в других файлах.
static int file_local_var = 10; // Внутреннее связывание. Видна только в module.cpp.

void foo() {
    // Обе переменные доступны здесь.
}
// File: main.cpp
extern int global_var; // Корректно: ссылаемся на переменную из module.cpp
// extern int file_local_var; // Ошибка компоновки: переменная не видна в этом файле.

int main() {
    int x = global_var; // OK
    // int y = file_local_var; // Не скомпилируется
    return 0;
}

Ключевые моменты:

  • Время жизни у обеих — вся программа (статическая память).
  • Инициализация: обе инициализируются нулём (для встроенных типов), если инициализатор не указан явно.
  • Использование static — хорошая практика для скрытия вспомогательных глобальных состояний внутри модуля.