简体   繁体   中英

Is it preferred/okay to use structure-initialization ({…}) over memset, etc.?

Code:

WINDOWPLACEMENT wplcmt = {sizeof(WINDOWPLACEMENT)};

Looks so much cleaner than:

WINDOWPLACEMENT wplcmt;
memset(&wplcmt, 0, sizeof(WINDOWPLACEMENT));
wplcmt.length = sizeof(WINDOWPLACEMENT);

The assembly output of this thing is also pretty nice, for longer structures MSVC even uses memset instead of xor eax, eax and mov 's. And from standard point of view it also looks ok. But I'm still scared about border cases where the structure is not tightly packed say #pragma pack(128) , and windows suddenly decides to do a memcmp of the structure.

So is it good/bad to use such syntax? Is it good practice to use such initializations?

The second code you show,

WINDOWPLACEMENT wplcmt;
memset(&wplcmt, 0, sizeof(WINDOWPLACEMENT));
wplcmt.length = sizeof(WINDOWPLACEMENT);

is beyond horrible. Obfuscation, inefficiency, verbosity, you crammed it all into that.

The first code snippet,

WINDOWPLACEMENT wplcmt = {sizeof(WINDOWPLACEMENT)};

is, except for the obfuscation, the preferred way, unless you want to

  • spend more time needlessly writing more code,

  • have readers spending more time reading and needlessly analyzing your verbose code,

  • get less efficient execution, and

  • provide bug entry portals.

By the way, what's with the obfuscated name you used, wplcmt ?

Why are you obfuscating names?

Is your question real or is it simply trolling?

Cheers & hth.,

EDIT : the question has been edited. The above questions were in response to the original title/question, "How evil is this structure allocation?". I'm leaving my answer as-is to provide context for the comments.

EDIT 2 : the context has changed even further: the OP's nick changed from "Madman" to "Coder". So, while the original was about "How eveil is" normal code by "Madman", it's now about "Is it preferred..." by "Coder". Oh well, I mean, I'm not calling him "Madman" in the commentary, as it would appear now; it's what he called himself, his nick at the time.

Use memset. Then everyone immediately sees what the code does and it's very unlikely to have any unexpected side-effects.

This kind of initialization I fight with constantly. In C99 one can do:

WINDOWPLACEMENT wplcmt = {.length = sizeof(wplcmt), .showCmd = SW_SHOW};

And the other values are zero-initialized.

In G++ you can do:

WINDOWPLACEMENT wplcmt = {length: sizeof(wplcmt), showCmd: SW_SHOW};

And lastly in C++, you can choose between initializing all members, or hope that you get the member order right like this:

WINDOWPLACEMENT wplcmt = {sizeof(wplcmt)};
WINDOWPLACEMENT wplcmt = {sizeof(wplcmt), 0, SW_SHOW, {0, 0}, {0, 0}, {0, 0, 0, 0}};

In fact in this last case, I'm not even sure all C++ compilers support compound literal initialization. Furthermore If the members change order, or type, and your values still fit you won't get an error.

Personally I choose to use C99 where I can, I would declare the struct you've given in one hit, with all the known values up front like this:

WINDOWPLACEMENT const wplcmt = {.length = sizeof(wplcmt), .showCmd = SW_SHOW};

Update0

It would seem that the "initialize all" I referred to is only for arrays? My mistake, this makes C++ slightly more usable.

If you use Visual Studio I strongly encourage you to use:

WINDOWPLACEMENT wplcmt;
SecureZeroMemory((LPVOID)&wplcmt, sizeof(WINDOWPLACEMENT));
wplcmt.length = sizeof(WINDOWPLACEMENT);

because the optimizing compiler could totally remove the memset call from your generated code, causing a lot of headaches if you really need to set those values to zero.

SecureZeroMemory will never be removed.

memset应该有更好的性能,因为它通常用高优化的asm编写

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