Членская структура может быть нулем-init из списка инициализатора конструктора, не звоня memset?

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

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 к списку инициализации конструктора без параметров следующим образом:

CFoobar::CFoobar()
: _foo()
{

То, что это, кажется, обнуляет членские переменные _foo. По крайней мере, это имело место с g ++ на Linux.

Теперь вот мой вопрос: Этот стандартный C++ или является этим компилятором определенное поведение?

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

20
задан selbie 12 May 2010 в 07:27
поделиться

3 ответа

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

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

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

11
ответ дан 30 November 2019 в 01:24
поделиться

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

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

1
ответ дан 30 November 2019 в 01:24
поделиться

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

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

Раздел 8.5

2
ответ дан 30 November 2019 в 01:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: