Хорошо, чтобы объявить статическую глобальную переменную.H-файл?
ключевое слово static сохраняет область глобальной переменной, ограниченную этой единицей перевода.
Если я использую static int x
в a .H-файл и включить этот .H файл каждый другой файл, не все ли они принадлежат к одной и той же единице перевода?
Тогда разве x не будет виден повсюду?
Так какова же роль статики сейчас?
кроме того, есть ли какое-либо использование static const int x
,где X-глобальная переменная?
Разве не все глобальные переменные const статичны по умолчанию?
И область действия переменной const ограничена TU, даже если он ограничен в цикле for в файле?
6 ответов
если вы пишите
static const int x
на .h файл, то каждый блок перевода, что #include-это .h будет иметь свою собственную частную переменную x
.
если вы хотите иметь 1 глобальную переменную, видимую всем, вы должны написать
extern const int x;
на .h файл и
const int x = ...;
в одном из .cpp файлы.
если вы хотите иметь статический const int видимым для только одна единица перевода - не упоминайте об этом в .h файлов.
Если я использую статический int x в a .H-файл и включить этот .H каждый файл другой файл, разве все они не принадлежат к одной и той же переводческой единице?
Если вы объявляете что-то как статическое (не внутри класса, поскольку ключевое слово class static имеет другую семантику), эта статическая переменная не может быть видна вне ее TU. Поэтому, помещая его в файл заголовка, каждый TU, включая этот заголовок, будет иметь другую частную копию этой статической переменной.
и область видимости переменной const ограничена TU, даже если она ограничена в цикле for в файл?
нет. Даже для статического значения const область определяется его объявлением. Таким образом, область будет ограничена вашими скобками.
вы в конечном итоге получите частные копии этой переменной на перевод, что приведет к раздуванию, если вы поместите его туда. было бы также бессмысленно иметь случайные копии по всему месту. нет, не в порядке.
вы можете объявить const int
на namespace
блок, то это нормально.
наблюдаемая разница для переменных, которые являются const
квалифицированный это в static
версия вы получите одну копию на единицу перевода, и поэтому сравнение адресов двух таких копий может завершиться неудачей.
если вы не используете адрес const
переменная любой современный компилятор должен иметь возможность просто использовать значение и оптимизировать саму переменную. В таком случае static
const
-квалифицированная переменная полностью в порядке.
в основном, каждый исходный файл вместе со всеми включенными файлами заголовков является одной единицей перевода. Поэтому, если у вас есть статическая переменная в файле заголовка, она будет уникальной в каждом исходном файле (единице перевода), в который включен файл заголовка.
"static global" не имеет смысла, они в некотором роде противоположны друг другу.
термин "глобальный" часто неправильно используется для описания переменной, объявленной вне любой функции в объем файла. Но скорее глобальная переменная-это одна с внешняя связь, к которому может получить доступ любой файл в проекте-следовательно, глобальный.
противоположность внешней связи внутренняя перелинковка, что означает, что переменная может получить только доступ к ЕП где он объявлен. Единица перевода, означающая один .c
файл и все заголовки, включенные в него (рекурсивно).
static
является гарантией того, что переменная получает внутреннюю связь. Таким образом, другой перевод не сможет получить к нему доступ или объявить extern
переменные, относящиеся к нему.
что произойдет, если объявить static
переменная в заголовочном файле - это то, что несколько единиц перевода получат отдельную переменную с таким именем. Код будет компилироваться нормально, хотя умные компоновщики заметят это и дадут ошибку компоновщика. Такие ошибки компоновщика часто не описательны и их трудно отследить.
это приводит нас к следующим рекомендациям:
- не объявить любой переменные в заголовочном файле, как это часто создает тонкие ошибки и ошибки компоновщика.
-
чтобы предотвратить такие ошибки, всегда окружайте все заголовочные файлы " header охранники":
#ifndef MYHEADER_H #define MYHEADER_H /* contents of header */ #endif
все переменные, объявленные в области файла, должны быть объявлены
static
, для личного заключения и не загромождают пространство. Аналогично,extern
следует избегать, так как это приводит к плохому дизайну и программированию спагетти.