Статические простые типы C ++ инициализируются по порядку? - PullRequest
3 голосов
/ 16 октября 2010

Мой опыт подсказывает мне, что для данного объекта:

class Object
{
private:
    static int array[];

public:
    Object(int id);
};


int Object::array[] = { 2937, 892 };


Object::Object(int id)
{
    // do something
}

Инициализация array произойдет до вызова любого метода на Object или вызова любого метода на любом другом объекте впрограмма независимо от того, объявлен ли объект static или нет.

По сути, я спрашиваю, не согласен ли кто-нибудь с тем, что статические простые типы C (не-объекты), такие как char, short, int и long (и структуры без конструкторов, состоящих из этих типов) инициализируются при загрузке исполняемого файла в память перед вызовом main () или любого другого конструктора?

Ответы [ 5 ]

7 голосов
/ 16 октября 2010

Конкретный тип инициализации, о котором, я думаю, вы говорите:

По сути, я спрашиваю: неужели кто-то не согласен с тем, что статические простые типы C (не-объекты), такие как char,short, int и long (и структуры без конструкторов, состоящих из этих типов) инициализируются при загрузке исполняемого файла в память перед вызовом main () или любого другого конструктора?

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

  • 3.6.2 инициализация нелокальных объектов

Объекты со статической продолжительностью хранения (3.7.1) должны быть инициализированы нулями (8.5) перед любой другой инициализацией.Обнуление инициализации и инициализация с постоянным выражением вместе называются статической инициализацией;все остальные инициализации - это динамическая инициализация. Объекты типов POD (3.9) со статической продолжительностью хранения, инициализированной с помощью константных выражений (5.19), должны быть инициализированы перед любой динамической инициализацией. Объекты со статической продолжительностью хранения, определенной в области пространства имен в той же единице перевода и динамическиinitialized должно быть инициализировано в том порядке, в котором их определение появляется в единице перевода.

Однако инициализация, такая как

static int x = getvalue();

, попадает в категорию динамической инициализации, поэтому она получаетупорядочено по внешнему виду (и неопределенно между различными единицами перевода).

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

7 голосов
/ 16 октября 2010

Да, вся статическая инициализация происходит до вызова main ().Но вы не можете быть уверены, в каком порядке происходит инициализация.Это может вызвать хаос, когда одна статическая переменная зависит от существования другой.Это называется статическим провалом инициализации: http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.14

Я часто использую решение, упомянутое в faq.Используйте функции со статическими переменными внутри, чтобы лучше контролировать порядок.

4 голосов
/ 16 октября 2010

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

2 голосов
/ 16 октября 2010

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

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

0 голосов
/ 16 октября 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...