Может ли структура-член иметь нулевую инициализацию из списка инициализатора конструктора без вызова memset? - PullRequest
20 голосов
/ 12 мая 2010

Допустим, у меня есть следующее объявление структуры (простая структура без конструктора).

struct Foo
{
    int x;
    int y;
    int z;
    char szData[DATA_SIZE];
};

Теперь предположим, что эта структура является членом класса C ++ следующим образом:

class CFoobar
{
     Foo _foo;
public:
     CFoobar();
};

Если я объявлю конструктор CFoobar следующим образом:

CFoobar::CFoobar()
{
    printf("_foo = {%d, %d, %d}\n", _foo.x, _foo.y,_foo.z);
    for (int x = 0; x < 100; x++)
       printf("%d\n", _foo.szData[x]);
}

Как и следовало ожидать, при запуске конструктора CFoobar выводятся мусорные данные. Очевидно, что легко исправить это с помощью memset или ZeroMemory & _foo. Это то, что я всегда делал ...

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

CFoobar::CFoobar()
: _foo()
{

Это, по-видимому, обнуляет переменные-члены _foo. По крайней мере, так было в случае с g ++ в linux.

Теперь вот мой вопрос: это стандарт C ++ или специфическое поведение этого компилятора?

Если это стандартное поведение, может кто-нибудь процитировать мне ссылку из официального источника? Какие-нибудь "ошибки" в отношении неявного поведения с нулевой инициализацией с более сложными структурами и классами?

Ответы [ 3 ]

11 голосов
/ 12 мая 2010

Да, это определенное поведение в соответствии со стандартом. 12.6.2 [class.base.init] / 3: "если список выражений mem-initializer опущен, базовый класс или подобъект члена имеет значение -initialized . "

Имейте в виду, однако, что если Foo не является POD-типом, но все еще не имеет объявленного пользователем конструктора (например, он имеет тип std::string), то некоторые очень популярные компиляторы не будут правильно value- инициализировать it.

Все известные мне компиляторы правильно выполняют инициализацию значений членов POD при использовании () в качестве инициализатора в списке инициализатора конструктора.

2 голосов
/ 12 мая 2010

мне трудно читать стандарт, но я нашел его, я думаю:

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

Раздел 8.5

1 голос
/ 12 мая 2010

Это эквивалент float foo = float();

Он обнулит объект, даже если представление значения не является нулем всех бит То есть это даже лучше чем memset().

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