Any reason to prefer memset/ZeroMemory to value initialization for WinAPI structs?

吃可爱长大的小学妹 提交于 2019-12-30 05:59:10

问题


In Win32 programming a handful of POD structs is used. Those structs often need to be zeroed out before usage.

This can be done by calling memset()/ZeroMemory()

STRUCT theStruct;
ZeroMemory( &theStruct, sizeof( theStruct ) );

or by value initialization:

STRUCT theStruct = {};

Although the two variants above are not equivalent in general:

  • treat padding differently
  • treat non-POD member variables differently

in case of POD structs used in Win32 they look equivalent.

Are there any cases when memset()/ZeroMemory() should be used instead of value initialization with Win32 POD structs?


回答1:


I always use:

STRUCT theStruct = {}; // for C++, in C use {0}

It's shorter, standard, therefore more elegant, and I don't really care about the theoretical differences. We are talking about code for a concrete OS here.

Another advantage is you can also immediately set the struct size in the first member like this:

STRUCT theStruct = {sizeof(STRUCT)}; 

Many Win32 structs require you to set the size in a first member.




回答2:


In Win32, ZeroMemory is just a Macro around RtlZeroRemory, which is a macro to memset. So, I don't think it makes a difference.

WinBase.h:

\#define ZeroMemory RtlZeroMemory"

WinNT.h:

\#define RtlZeroMemory(Destination,Length) memset((Destination),0,(Length))



回答3:


If your code will serve as an example to countless Visual Basic developers who are likely to not notice or understand the C++ = {} construct, ZeroMemory is a good way to make the C++ code look more like pseudocode and minimize the incidence of subtle, hair-ripping initialization bugs.

That's the concern that the MSDN article authors faced, which then explains why ZeroMemory shows up in so much code (even C++ code).

On the other hand, if the purpose of your C++ code is to make a working product, rather than to teach the world, using the elegant and expressive power of the C++ language is a great idea.




回答4:


The only reason (that I can foresee) to not use value initialization for 'zeroing' is if you have special versions of memset/ZeroMemory(such as an SSE based one), or you need to avoid problems with the compiler(referring to MSVC here, as from VS2008 memset will never become an intrinsic, but with some clever coding(not using asm) you can force the intrinsic(REP STOS))




回答5:


The only reason to prefer memset/ZeroMemory for this kind of initialization is if WinAPI functions require/expect the memory to be initialized that way, i.e. if WinAPI functions expect their zeros to be physical zeros - values with all-zero bit patterns.

Keep in mind that the difference between a representation of a zero value of some type and physical all-zero-bit pattern depends on the compiler implementation, not on OS. In theory, a Windows compiler can use non-zero bit patterns to represent zero values of various types. Like, a null pointer might be represented by non-zero physical value in some imaginary C or C++ compiler for Windows. (Not that anyone would actually do that, of course).




回答6:


The end result is identical (so long as you assume that 0 is always represented by all-zero-bits), so it's largely a matter of style. Personally, I prefer value initialisation, since it is simpler and doesn't require function calls.

Incidentally, you must initialise at least one member:

STRUCT theStruct = {0};

Omitting the 0 is allowed by some C compilers, but not by the C standard. C++ allows the omission, but I prefer to just always use the 0.




回答7:


in c++11:

struct A {
    int x = 10;
    int y = 100;
    int z = 0;
};

old style c++

struct A {
    int x;
    int y;
    int z;
    A() : x( 10 ), y( 100 ), z( 0 ) {} //constructor
};


来源:https://stackoverflow.com/questions/3853339/any-reason-to-prefer-memset-zeromemory-to-value-initialization-for-winapi-struct

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!