C++ 在memset等之上使用结构初始化({…})是否更可取/可以。?

C++ 在memset等之上使用结构初始化({…})是否更可取/可以。?,c++,c,windows,initialization,C++,C,Windows,Initialization,代码: 看起来比: WINDOWPLACEMENT wplcmt = {sizeof(WINDOWPLACEMENT)}; 这个东西的汇编输出也很好,对于较长的结构,MSVC甚至使用memset而不是xor eax、eax和mov。从标准的角度来看,它看起来也不错。但我仍然担心结构没有紧密封装的边界情况,比如说#pragma pack(128),windows突然决定对结构进行memcmp 那么使用这种语法是好还是坏呢? 使用这种初始化是否是一种良好的做法?使用memset。然后每个人都会立即

代码:

看起来比:

WINDOWPLACEMENT wplcmt = {sizeof(WINDOWPLACEMENT)};
这个东西的汇编输出也很好,对于较长的结构,MSVC甚至使用
memset
而不是
xor eax、eax
mov
。从标准的角度来看,它看起来也不错。但我仍然担心结构没有紧密封装的边界情况,比如说
#pragma pack(128)
,windows突然决定对结构进行memcmp

那么使用这种语法是好还是坏呢?
使用这种初始化是否是一种良好的做法?

使用memset。然后每个人都会立即看到代码的作用,并且不太可能产生任何意外的副作用。

您显示的第二个代码

WINDOWPLACEMENT wplcmt;
memset(&wplcmt, 0, sizeof(WINDOWPLACEMENT));
wplcmt.length = sizeof(WINDOWPLACEMENT);
这太可怕了。混乱、低效、冗长,都是你塞进的

第一个代码段

WINDOWPLACEMENT wplcmt;
memset(&wplcmt, 0, sizeof(WINDOWPLACEMENT));
wplcmt.length = sizeof(WINDOWPLACEMENT);
是,除了模糊处理,首选的方式,除非您愿意

  • 花更多时间不必要地编写更多代码

  • 让读者花更多的时间阅读和不必要地分析你冗长的代码

  • 执行效率较低,并且

  • 提供bug入口

顺便问一下,您使用的模糊名称是什么,
wplcmt

你为什么混淆名字

你的问题是真的还是简单的胡扯

干杯

编辑:问题已编辑。上述问题是对原标题/问题“这种结构分配有多邪恶?”的回应。我留下我的答案是为了提供评论的背景


编辑2:背景发生了更大的变化:OP的尼克从“疯子”变成了“编码员”。所以,虽然原著是“疯子”写的“eveil是怎样的”普通代码,但现在是“编码器”写的“它是首选的…”。哦,我的意思是,我不是在评论中称他为“疯子”,就像现在看起来的那样;这就是他所谓的自己,他当时的尼克。

我经常与这种初始化斗争。在C99中,可以执行以下操作:

WINDOWPLACEMENT wplcmt = {sizeof(WINDOWPLACEMENT)};
其他值初始化为零

在G++中,您可以执行以下操作:

WINDOWPLACEMENT wplcmt = {.length = sizeof(wplcmt), .showCmd = SW_SHOW};
最后,在C++中,您可以在初始化所有成员之间进行选择,或者希望您获得这样的成员顺序:

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

实际上,在最后一个例子中,我甚至不确定所有C++编译器都支持复合文字初始化。此外,如果成员更改了顺序或类型,并且您的值仍然合适,则不会出现错误

就我个人而言,我选择在可能的情况下使用C99,我会声明您在一次点击中给出的结构,所有已知值如下:

WINDOWPLACEMENT wplcmt = {length: sizeof(wplcmt), showCmd: SW_SHOW};
WINDOWPLACEMENT wplcmt = {sizeof(wplcmt)};
WINDOWPLACEMENT wplcmt = {sizeof(wplcmt), 0, SW_SHOW, {0, 0}, {0, 0}, {0, 0, 0, 0}};
更新0
我提到的“初始化全部”似乎只针对数组?我的错误,这使得C++更易于使用。

内存集应该有更好的性能,因为它通常是用高优化的ASM/P>P>P编写的。如果你使用Visual Studio,我强烈鼓励你使用:

WINDOWPLACEMENT const wplcmt = {.length = sizeof(wplcmt), .showCmd = SW_SHOW};
因为优化编译器可能会从生成的代码中完全删除memset调用,如果您真的需要将这些值设置为零,则会带来很多麻烦


SecureZeroMemory将永远不会被删除。

+1。我同意。尤其是因为这是一个用于初始化本机Windows结构的长期习惯用法。。。。如果我们关心的是“惯用”和特定于本机Windows,那么不应该使用ZeroMemory()而不是memset()?:)如果这个结构有一个指针类型,指针不是所有的位都是零,或者浮点值也可能不是所有的位都是零,IIRC呢?然后我们也显式地设置这些值。给定Windows类的文档将告诉我们应该做什么来初始化它。这听起来像是一个拖拉问题。在我看来,两者都可以,但为什么Windows(或其他任何东西)会memcmp该结构?首先,在具有未使用位的结构上执行memcmp肯定是不明智的。不要求这些未使用的填充字节为零(或任何其他值),因此认为它们的任何比较都是无效的。是否有任何东西真的做到了这一点,或者你担心它“以防万一?”一旦它超出了你的代码,你就无法确定接下来会发生什么。所以我只是想知道如何编写更干净、更健壮的代码。我更喜欢单行程序方法,但正如我所提到的,填充和memcmp可以打破混乱。假设我有结构{int32_t v1,int16_t v2/*不存在填充int16_t*/},我用={}初始化,但是我调用的库,用ZeroMemory或memset初始化同一结构的另一个副本,并执行memcmp。我的结构中的填充值是未定义的,对吧,并且可以返回结构是不同的,即使实际的成员变量相等。很抱歉混淆了,这只是一个假设的代码,我倾向于在任何地方使用可读性好的名称。你的答案是好的(事实上),但是,你不应该无缘无故地指责其他人。正因为如此,你的答案不会赢得我的选票…@Madman:如果可以的话,请避免使用检查填充字节是否为零的库。或者表现出其他未定义的行为。:-)@杰帕莱切克:我不是在指责,只是在问,这不是没有理由的,这是出于所陈述的理由。考虑一下:一个“疯子”,把微软作为一个低级别C代码,被标记为C++,并询问“邪恶”代码是如何比较的,这就意味着它不能更好。对我来说,听起来像TrutLink C/C++是因为尽管我尽可能多地编写C++,但至少没有人将WiLAPI转换成C++。因此,如果有人知道一个干净的C++解决方案,它是受欢迎的。关于更正常的问题,到目前为止,我们有两个完全相反的答案,因此,尽管我也喜欢您所捍卫的解决方案,但我还不确信它是好的。“WINDOWPLACEMENT wplcmt={sizeof(wplcmt)};//所有成员都设置为sizeof(wplcmt)”其他值不是设置为0吗?通过“in G++”,您的意思是“in GNU C++”,