Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Статические простые типы С++ инициализируются по порядку?

Автор вопроса: MatthewОтветов: 5

Мой опыт говорит мне, что данный объект:

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() или любого другого конструктора?

c++typesstatic

Ответы

Ответ 1 · рейтинг 7 · miked

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

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

Ответ 2 · рейтинг 7 · Michael Burr

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

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

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

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

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

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

static int x = getvalue();

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

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

Ответ 3 · рейтинг 4 · Oliver Charlesworth

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

Ответ 4 · рейтинг 2 · Klaim

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

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

Ответ 5 · Puppy

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

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы