У меня есть много структур POD с большим количеством переменных-членов. Вместо инициализации каждого члена в конструкторе, я просто использую memset. Это действительно в C ++?
struct foo
{
foo() { std::memset(this, 0, sizeof (foo)); }
int var1;
float var2;
double var3;
// more variables..
};
Работать не гарантируется, поскольку стандарт C ++ допускает реализации, в которых все биты-ноль представляют собой ловушку float
или же double
, Таким образом, чтение этих членов в такой реализации будет иметь неопределенное поведение.
То же самое относится и к любым байтам заполнения, которые реализация может поместить между элементами данных — их изменение либо неопределенное поведение, либо переводит объект в неопределенное состояние, которое при использовании имеет неопределенное поведение. Я забыл, что.
На практике это будет работать на всех реализациях, которые я знаю.
Другие ответы подтверждают, что ваш класс не POD (C ++ 03) и нетривиален (C ++ 11). Дело в том, даже если вы удалили конструктор и вызвали memset
откуда-то еще еще не гарантируется работа по стандарту. Но если вы удалили конструктор, вы можете использовать агрегатную инициализацию:
foo f = {0};
и это гарантировало бы инициализацию всех членов к нулевым значениям (независимо от того, представлено ли это как все биты с нулем).
В соответствии со стандартом ваша структура не является POD-типом, и поэтому ей запрещено использовать memset.
Тривиальный класс — это класс, который имеет конструктор по умолчанию (12.1), не имеет нетривиальных конструкторов по умолчанию ,
и тривиально копируемый
10 POD struct108 — это класс, не являющийся объединением, который является как тривиальным классом, так и классом стандартной компоновки и не имеет
нестатические члены-данные типа non-POD struct, non-POD union (или массив таких типов).
Поскольку ваш класс имеет нетривиальный конструктор по умолчанию, он больше не является тривиальным и, как результат, не является POD-типом.
Скорее всего, будет работать на большинстве компиляторов, без гарантии.