问题描述
时常数据结构有效初始化所有成员设置为零。在C ++编程即使当,可以需要与外部的API的量是这样的接口
Oftentimes data structures' valid initialization is to set all members to zero. Even when programming in C++, one may need to interface with an external API for which this is the case.
有没有之间的任何实际差别:
Is there any practical difference between:
some_struct s;
memset(&s, 0, sizeof(s));
和简单
some_struct s = { 0 };
别人发现自己同时使用,有一种方法用于选择哪一个更适合于给定应用程序? (但愿据了解,这是目前仅适用于POD结构;你会得到各种混乱的,如果有一个C ++的std ::字符串中的结构)
Do folks find themselves using both, with a method for choosing which is more appropriate for a given application? (Hopefully it is understood that this is only currently applicable to POD structures; you'd get all sorts of havoc if there was a C++ std::string in that structure.)
有关我自己,因为大多是C ++程序员谁不使用memset的太多,我从来没有某些的函数签名,所以我觉得第二个例子只是为了更容易被除了使用少打字,更紧凑,甚至可能更明显,因为它说:这个对象初始化为零就在声明中,而不是等待code的下一行,看,哦,这个对象是初始化为零。
For myself, as mostly a C++ programmer who doesn't use memset much, I'm never certain of the function signature so I find the second example is just easier to use in addition to being less typing, more compact, and maybe even more obvious since it says "this object is initialized to zero" right in the declaration rather than waiting for the next line of code and seeing, "oh, this object is zero initialized."
在用C创建类和结构++我倾向于使用初始化列表;我很好奇的两个C风格的初始化人们的思想上面,而不是对什么是在C ++中提供一个比较,因为我怀疑我们许多人用,即使我们code主要是在C ++自己的C库接口。
When creating classes and structs in C++ I tend to use initialization lists; I'm curious about folks thoughts on the two "C style" initializations above rather than a comparison against what is available in C++ since I suspect many of us interface with C libraries even if we code mostly in C++ ourselves.
编辑:尼尔·巴特沃思提出,在后续,我认为这是一个有趣的推论这个问题。
Neil Butterworth posed this question, in followup, that I believe is an interesting corollary to this question.
推荐答案
memset的
实际上从来没有做到这一点的正确方法。是的,有实际意义(见下文)。
memset
is practically never the right way to do it. And yes, there is a practical difference (see below).
在C ++中不是什么都可以用文字初始化 0
(枚举类型的对象不能),这就是为什么在C ++中常见的成语是
In C++ not everything can be initialized with literal 0
(objects of enum types can't be), which is why in C++ the common idiom is
some_struct s = {};
而在C中的成语是
while in C the idiom is
some_struct s = { 0 };
请注意,即在C = {0}
什么是可以被称为的通用零初始化的。它可以与几乎任何类型的对象一起使用,因为 {}
-enclosed初始化被允许标量对象以及
Note, that in C the = { 0 }
is what can be called the universal zero initializer. It can be used with objects of virtually any type, since the {}
-enclosed initializers are allowed with scalar objects as well
int x = { 0 }; /* legal in C (and in C++) */
这使得 = {0}
在泛型类型无关的C code有用的(类型无关的宏为例)。
which makes the = { 0 }
useful in generic type-independent C code (type-independent macros for example).
= {0} C89 / 90和C ++
初始化的缺点是,它只能作为声明的一部分。 (C99引入解决了这个问题的复合文字的。类似的功能来C ++为好。)因此,你可能会看到很多程序员使用 memset的
以零出来的东西在C89 / 90或C ++中的code的中间。然而,我想说,做正确的方式是仍然没有 memset的
,而是用类似
The drawback of = { 0 }
initializer in C89/90 and C++ is that it can only be used as a part of declaration. (C99 fixed this problem by introducing compound literals. Similar functionality is coming to C++ as well.) For this reason you might see many programmers use memset
in order to zero something out in the middle of C89/90 or C++ the code. Yet, I'd say that the proper way to do is still without memset
but rather with something like
some_struct s;
...
{
const some_struct ZERO = { 0 };
s = ZERO;
}
...
即。通过在code中间引入一个虚构的块,即使它可能看起来不太pretty一见钟情。当然,在C ++中有没有必要引入一个块。
i.e. by introducing a "fictive" block in the middle of the code, even though it might not look too pretty at the first sight. Of course, in C++ there's no need to introduce a block.
至于实际的区别...你可能会听到一些人说 memset的
将产生在实践中相同的结果,因为在实践中的物理全零位模式正在使用什么重新present所有类型的零值。然而,这通常是不正确的。这将表明在一个典型的C ++实现的差异一个直接的例子是一个指针到数据成员类型
As for the practical difference... You might hear some people say that memset
will produce the same results in practice, since in practice the physical all-zero bit pattern is what is used to represent zero values for all types. However, this is generally not true. An immediate example that would demonstrate the difference in a typical C++ implementation is a pointer-to-data-member type
struct S;
...
int S::*p = { 0 };
assert(p == NULL); // this assertion is guaranteed to hold
memset(&p, 0, sizeof p);
assert(p == NULL); // this assertion will normally fail
这是因为典型的实现通常采用全1位模式( 0xFFFF的...
)重新present这种类型的空指针。上面的例子演示之间的现实生活中的实际差异归零 memset的
和正常 = {0}
初始化。
This happens because a typical implementation usually uses the all-one bit pattern (0xFFFF...
) to represent the null pointer of this type. The above example demonstrates a real-life practical difference between a zeroing memset
and a normal = { 0 }
initializer.
这篇关于初始化的对象为全零的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!