简体   繁体   中英

Is it good style to memset a struct before using it?

Once I learned signals and there was a listing with handling signals.

There was a struct sigaction which was first memset() to all bytes zero with the following line:

memset(&sa, 0, sizeof(sa));

And I'm not sure why author uses this approach.

As you've already been told, trying to read values from uninitialized members of a structure leads to undefined behaviour. That is unconditionally bad. Therefore, it is incumbent upon you to ensure that all fields are initialized before they're read.

If you know all the elements of the structure and are going to initialize them explicitly, then the memset() is not necessary. This can be manageable if the structure is under your control — you just have to remember to ensure that all the places where initialization takes place are updated when you add new members to the structure. If you write a function to do that (think 'C analogue of C++ constructor', to a first approximation), then the memset() can be left out. If you set the values ad hoc in many places, you've probably got problems if the structure changes.

In the case of something like struct sigaction , it is from a system-defined header, and different systems can (and do) add extra fields to the structure — over and above the ones you plan to initialize. Note that POSIX only specifies the fields that must be present; it does not dictate the order of the fields, nor does it mandate that there are no other fields in the structure. However, the functions using the extra (non-POSIX) elements of the structure should not do so unless the user indicates that those members are initialized, usually with some explicit flag, so you shouldn't run into problems — but it is better safe than sorry.

Consequently, in contexts where you don't have control over the structure, the memset() approach is readily defensible: it is guaranteed to zero all of the structure, even the bits you don't know about — even if the structure definition changes (grows) after the code is written.

You may be able to use struct sigaction sa = { 0 }; or struct sigaction *sap = calloc(sizeof(*sap), 1); to zero the structure instead — it depends in part on how fussy a set of compiler options you use (and also the version of the compiler you use; GCC has changed its behaviour over time, for example).

You might want to look up macros such as PTHREAD_MUTEX_INITIALIZER in the POSIX standard — or you may prefer to ignore their existence altogether.

Uninitialized variable contains indeterminate values, use of them are often cause of program failures, so you will need to initialize a variable before use it. But you don't have to use memset to do it, you can use initializer:

struct sigaction sa = {0};

this way a function call is saved, and it's easy for the reader of the code to spot it is initialized.

When you declare a struct without an initializer, it is undefined behavior to use any of that struct 's members without assigning them first. If you would like to put zeros into all members of the struct , memset provides a good approach to do so.

If you plan to assign all members of the struct anyway, the call to memset is unnecessary.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM