Подтвердить что ты не робот

Статические переменные внутри функций на С++ - выделены, даже если функция не запускается?

Я читал на С++ в Интернете, и вот одна вещь, на которую я не смог найти ответ.

Я знаю, что статические переменные, используемые в функциях, схожи с глобальными, а последующие вызовы этой функции будут иметь статическую переменную, сохраняющую ее значение между вызовами.

Однако, если функция никогда не вызывается, получает ли статическая переменная?

Спасибо

4b9b3361

Ответ 1

Если функция никогда не вызывается, вероятно, ваш компоновщик отключит как функцию, так и статическую переменную, не позволяя ей входить в сегменты .rodata, .data или .bss (или эквиваленты вашего исполняемого файла).

Однако существуют разные причины, по которым компоновщик не может отключаться (флаги говорят, что это не так, невозможность определить, что зависит от символа и т.д.).

Стоит проверить файл вашей компоновщика (иногда просто текстовый файл!) или использовать утилиты objdump, nm или dumpbin в конечном исполняемом файле, чтобы увидеть, есть ли символ или связанные символы (такие как статические код инициализатора).

Ответ 2

В стандарте С++, раздел 6.7 говорится:

Нулевая инициализация (8.5) всех локальные объекты со статическим хранилищем продолжительность (3.7.1) выполняется до любая другая инициализация имеет место. Локальный объект типа POD (3.9) с статическая длительность хранения с постоянными выражениями инициализируется перед первым блоком вошел. Реализация разрешено выполнять ранние инициализация других локальных объектов с продолжительностью статического хранения в соответствии с те же условия, что реализация разрешено статически инициализировать объект со статической продолжительностью хранения в области пространства имен (3.6.2). В противном случае такой объект инициализируется контроль в первый раз проходит через выражение; такой объект считается инициализированным завершение его инициализации.

Что указывает, что локальные статические объекты обычно инициализируются при первом обращении к ним. Тем не менее, они могут быть выделены до этого - стандарт несколько сдержан относительно того, что на самом деле является статическим хранилищем, за исключением ссылок на статические объекты.

Ответ 3

Каждый объект в С++ имеет два вложенных периода времени, связанных с ним: продолжительность хранения и время жизни. Длительность хранения - это период, за который выделена необработанная память, занятая объектом. Время жизни - это период между построением и уничтожением реального объекта в этой памяти. (Для объектов типа POD-разрушение конструкции не имеет значения или не применимо, поэтому их срок службы соответствует длительности их хранения).

Когда кто-то говорит "распределенный", они обычно ссылаются на продолжительность хранения. Язык не указывает точно, когда начинается длительность хранения объекта. Достаточно потребовать, чтобы это началось в какой-то момент до начала жизни объекта.

По этой причине в общем случае статический объект, определенный внутри функции, может никогда не начинать свое время жизни, и, теоретически, срок хранения не должен начинаться. Таким образом, теоретически, возможно, даже не получится "выделено".

На практике, однако, все объекты со статической продолжительностью хранения ( "глобальные", локальная статика и т.д.) обычно обрабатываются одинаково: им назначается определенное количество хранилища раньше, при запуске программы.


В качестве дополнительной заметки, если локальный объект со статической продолжительностью хранения требует нетривиальной инициализации, эта инициализация выполняется, когда элемент управления переходит к определению в первый раз. Итак, в этом примере

void foo() {
  static int *p = new int[100];
}

динамический массив никогда не будет выделен, если функция никогда не вызывается. И будет выделено только один раз, если вызывается функция. Это не похоже на то, о чем вы просите, но я упоминаю это на всякий случай.

Ответ 4

Я уверен, что это будет до реализации. Что MSVC делает - статические объекты выделяются в сегменте автоматической обработки EXE или DLL. Однако конструктор выполняется только при первом запуске функции, содержащей статику.

Ответ 5

Да, фактическое распределение зависит от компилятора, хотя я думаю, что каждый компилятор просто резервирует пространство в сегменте .static исполняемого файла (или эквивалент в его исполняемом файле).
Инициализация, однако, имеет место только в первое время, когда поток выполнения встречает статический объект, и это требуется стандартом.
Помните, что инициализация статических объектов global работает по-другому. Вы можете получить очень хорошие ответы почти на каждый вопрос на С++ FAQ lite. Я также увлекаюсь Скоттом Мейерсом "Эффективный С++".

Ответ 6

Зависит. Если вы имеете в виду, никогда не вызывается, как и в, функция буквально никогда не вызывается, то ваш компилятор, вероятно, не выделяет ее, или даже не вводит код функции. Если, однако, вы сделали это зависимым от, скажем, пользовательского ввода, и этот пользовательский ввод просто не появился, то он, вероятно, будет предварительно выделен. Тем не менее, вы наступаете на минное поле здесь, и лучше всего предположить, что он всегда создается элементом управления временем, входящим в функцию (ы), которые ссылаются на него.

Ответ 7

Статические переменные, определенные в классах (членах) или функциях, динамически не выделяются в стеке во время вызова функции, например, нестационарные. Они выделяются в другой области сгенерированного кода, зарезервированного для глобальных и статических данных. Таким образом, если вы вызываете функцию или нет, создавайте классы, содержащие статические элементы или нет, пространство для их данных будет зарезервировано в области данных программы в любом случае.