C 是否保证memset会将结构中的填充位归零?

C 是否保证memset会将结构中的填充位归零?,c,gcc,memset,C,Gcc,Memset,一般来说,按照C标准,是否可以保证带0的memset()会将C结构中的填充位归零 gcc呢 例如,类似于: struct MyStruct { unsigned char member1; unsigned int member2; char member3; unsigned char member4; float member5; }; struct MyStruct ms; memset(&

一般来说,按照C标准,是否可以保证带0的memset()会将C结构中的填充位归零

gcc呢

例如,类似于:

struct MyStruct
{
    unsigned char   member1;
    unsigned int    member2;
    char        member3;
    unsigned char   member4;
    float       member5;    
};

struct MyStruct ms;

memset(&ms, 0, sizeof( struct MyStruct));

是,
memset
将32位值写入给定长度的连续内存区域,从给定地址开始。在您的情况下,memset使用(32位值)
0
写入区域

因此,如果您使用长度
sizeof(您的结构)
memset
,您应该可以:

memset(&ms, 0, sizeof(struct MyStruct));

也许值得注意的是,
memset
对您的结构(或数组,或原语,或您碰巧打开它的任何内存块)一无所知,因此即使它想保留填充位不变,它也不知道它们在哪里。

如果有关系,你可能正在做一些不安全和不可携带的事情

是的,
memset
调用会将任何填充位(或字节)设置为0——但在该语言中,无法保证将
float
对象设置为所有位零会将其设置为0.0。指针也是如此:不能保证所有零位都是空指针。(在这两种情况下,大多数实现都是如此。)

最初的ISO C90或C99标准甚至不能保证所有位0对于整数类型都是0的有效表示;C99之后的技术勘误表之一添加了此类保证(仅适用于整数类型)

为了便于移植,如果您希望某个值为零,请显式设置它。对于静态对象和初始化器中省略的成员,还可以利用零值初始化


术语上的挑剔:“填充位”是整数类型表示的一部分(通常没有)。结构成员之间的填充就是填充字节。

你能给我们看一个代码示例吗?我不明白你为什么会怀疑。那么简短的回答:是的。它将使
ms
占用的整个内存区域归零。填充位和所有…@MK,我在某处看到一条评论,“不要使用memcmp结构,即使在使用它们之前您已经对这些结构进行了memset”。我的想法是,如果填充位已经被memset设置为0,那么以后使用memcmp就不会有任何问题。可能是我发现的引用是错误的。我认为这可能是一个好主意,不依赖memcmp来比较你的结构,因为如果你忘记在哪里设置memset,你的手上就会有一个难找的臭虫。因此,除非已经证明它是性能瓶颈,否则请编写显式比较函数。还可以想象这样一种情况:您有一个char buf[20],在一个结构中设置为“aaa”,在另一个结构中设置为“bbb”,然后将两者都设置为“c”。结构现在在逻辑上是相等的,但memcmp会将它们视为不同的;所有最近的编译器都知道
memset
的语义,并围绕这一点进行优化,而且编译器肯定知道填充的位置。