c ++ статическая инициализация POD - PullRequest
1 голос
/ 07 декабря 2010

У меня есть один экземпляр простого POD

a.hpp

class A {
    struct Zzz {
        A*  m_aPtr;
        int m_val;
    }

    static Zzz s_zzz;
};

a.cpp

A::Zzz A::s_zzz;

Я ожидаю, что s_zzz.m_aPtr и s_zzz.m_val будут инициализированы нулями перед любой другой статической инициализацией в любом другом модуле компиляции, и это гарантируется самим языком. Я прав?

Обычно я предоставляю конструкторы по умолчанию для структур. Скажем

A::Zzz::Zzz() :
 m_aPtr(0),
 m_val(0)
{
}

Будет ли это создавать проблему порядка инициализации или вводить зависимости компилятора?

Ответы [ 4 ]

2 голосов
/ 07 декабря 2010

По крайней мере в C ++ 0x вы можете положиться на все инициализацию нуля , выполняемую до запуска любого другого кода инициализации.

Из FCD C ++ 0x, раздел [basic.start.init]

Переменные со статической продолжительностью хранения (3.7.1) или продолжительностью хранения потока (3.7.2) должны быть инициализированы нулями (8.5) перед любой другой инициализацией.

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

2 голосов
/ 07 декабря 2010

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

Он будет инициализирован нулем, так как это статическая переменная времени жизни в области имен.

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

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

С вашей точки зрения 2, довольно неясно, о чем вы спрашиваете.

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

Приветствия и hth.,

ERRATA : Бен Фойгт предоставил убедительный пример того, что последний абзацвыше неправильно .Поэтому, пожалуйста, не обращайте внимания.Наличие конструктора означает, что объект может динамически инициализироваться в некоторый момент до, между или после операций, которые его изменяют, что приводит к довольно непредсказуемым результатам…

1 голос
/ 07 декабря 2010
  1. Нет никаких гарантий относительно порядка инициализации статики между блоками компиляции (см. http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.14).

  2. Если у него есть конструктор, он, к сожалению, больше не будет POD.

0 голосов
/ 07 декабря 2010
  1. Статические данные всегда обнуляются.
  2. Нет, это не должно вызывать проблем с инициализацией.

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

...