Как вы уже сказали, попытка считывания значений из неинициализированных элементов структуры приводит к неопределенному поведению. Это безусловно плохо. Поэтому вам необходимо убедиться, что все поля инициализированы до их чтения.
Если вы знаете все элементы структуры и собираетесь их инициализировать явно, то memset()
не требуется. Это может быть управляемо, если структура находится под вашим контролем - вам просто нужно помнить, что все места, где происходит инициализация, обновляются при добавлении новых членов в структуру. Если вы напишете функцию для этого (подумайте «аналог C конструктора C++», в первом приближении), то memset()
можно оставить без внимания. Если вы установите значения ad hoc во многих местах, у вас, вероятно, возникнут проблемы, если структура изменится.
В случае чего-то вроде struct sigaction
это из системного заголовка, а различные системы могут (и делать) добавлять дополнительные поля в структуру - сверх тех, которые вы планируете инициализировать. Обратите внимание, что POSIX указывает только те поля, которые должны присутствовать; он не диктует порядок полей и не требует, чтобы в структуре не было других полей. Тем не менее, функции, использующие дополнительные (не POSIX) элементы структуры, не должны делать этого, если пользователь не указывает, что эти элементы инициализированы, как правило, с некоторым явным флагом, поэтому вы не должны сталкиваться с проблемами - но это лучше безопасно чем жаль.
Следовательно, в условиях, когда у вас нет контроля над структурой, подход memset()
легко защищен: гарантируется нулевая вся структура, даже биты, о которых вы не знаете, даже если структура (увеличивается) после того, как код написан.
Вы можете быть в состоянии использовать struct sigaction sa = { 0 };
или struct sigaction *sap = calloc(sizeof(*sap), 1);
нуль структуры вместо этого - это отчасти зависит от того, как суетливой набор опций компилятора вы используете (а также версию компилятора вы используете, GCC изменила свое поведение в течение время, например).
Возможно, вы захотите найти макросы, такие как PTHREAD_MUTEX_INITIALIZER
, в стандарте POSIX, или вы можете вообще игнорировать их существование.
Нет. Но вы должны инициализировать переменную перед ее использованием. – Olaf
У _null pointers_ не гарантируется двоичное представление всего бита нуль. Аналогично для членов с плавающей запятой. Так что 'memset' - плохая идея. – Olaf
memset для инициализации структур иногда встречается в старом коде, который был написан до того, как составные литералы стали доступны на C99. – dpi