These two designs are very different in meaning. The first uses the memset function, which is designed to set the memory buffer to a specific value. The second is to initialize the object. Let me explain this with code:
Suppose you have a structure in which there are only members of POD types
struct POD_OnlyStruct { int a; char b; }; POD_OnlyStruct t = {};
In this case, the entry POD_OnlyStruct t = {} or POD_OnlyStruct t; memset(&t, 0, sizeof t) POD_OnlyStruct t; memset(&t, 0, sizeof t) doesn't really matter, since the only difference we have here is alignment bytes set to zero if memset used. Since you do not have access to these bytes, there is no difference.
On the other hand, since you marked your question as C ++, try a different example, with member types other than POD:
struct TestStruct { int a; std::string b; }; TestStruct t = {};
In this case, using an expression like TestStruct t = {} is good, and using memset on it will fail. Here, what happens if you use memset - an object of type TestStruct is created, thus creating an object of type std::string , since it is a member of our structure. Then memset sets the memory in which the object b was at a certain value, for example, zero. Now, as soon as our TestStruct object goes out of scope, it will be destroyed, and when the queue comes to it, the member std::string b you will see a failure, since all the internal structures of this object were destroyed by memset .
So, the reality is that these things are very different, and although in some cases you sometimes need a memset whole structure for zeros, it is always important to make sure that you understand what you are doing and not doing as in our second example.
My vote - use memset for objects only if necessary, and use the default initialization x = {} in all other cases.