Пушыстый (_winnie) wrote,
Пушыстый
_winnie

Categories:

C++, zero initialization

С++: Безопасный для поддержки и дальнейшей жизни проекта способ инициализации структуры из ста полей нулями.

http://www.everfall.com/paste/id.php?6ug9lmemxk29

T x = {}; //рекомендуется для типов без конструкторов

если конструктора и наследования нет, будет вызов дефолтных конструкторов/обнуление членов ("each member of the aggregate shall be initialized with a value of the form T()").
Если есть, компилятор ругнётся, но покрайней мере не будет никаких сюрпризов, которые могли бы быть если сделать:

T x = T(); //перестанет обнулять int-float члены встроеных типов, если добавить в T non-pod член или конструктор по умолчанию.
или
memset(&x, 0, sizeof(x)); //будет вести себя странно как только в T появятся виртуальные функции или non-pod члены.

Более точная информация - С++ Стандарт, 8.5.1 Aggregates

К сожалению, такой способ инициализации доставляет некоторые неудобства, когда сложно завести временную переменную, и надо инициализировать базовый класс или член или параметр функции (см. пример с http://www.everfall.com/paste/id.php?6ug9lmemxk29).
Можно обойти с помощью template <class T> T InitAggregate() { T x = {}; return x; }

PS. Если внутри T - под-члены с конструктором который оставляет неинициализированый мусор, то добраться до них можно только при помощи memset. Типичный пример:

struct Point 
{
   float x, y;
   Point() {} //ахтунг, x,y - неинициализированы!
};

struct T
{
  float scale;
  Point pos;
};


PPS. не люблю C++ за то, что вокруг каждой мелочи столько граблей и тайных знаний.

PPPS. В VC2005 появился __is_pod(type), __is_polymorphic(type)
. Можно ещё ставить ассерты перед memset.

PPPPS.
Справедливо напомнили, что если создаём не автоматические объекты на стеке, то можно занулить память перед созданием в ней объекта. Подумалось о ZeroBefore<T>, который обнуляет память _перед_ созданием объекта T в своём чреве. Но "как-то всё это через хитро закрученую жопу".

PPPPPS.
Справедливо напомнили, что в эльфийских рассылках usenet существуют странные компьютеры, где нулевой float и нулевой указатель не обязательно состоят из нулевых байтов, как ещё одна рекомендация не использовать memset.
Tags: c++
Subscribe
  • Post a new comment

    Error

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 27 comments