11

In general ,as per C standard is it guaranteed that memset() with 0 will zero out the padding bits in a C structure?

What about gcc?

For example , something like:

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

struct MyStruct ms;

memset(&ms, 0, sizeof( struct MyStruct));
Lunar Mushrooms
  • 8,358
  • 18
  • 66
  • 88
  • Can you show us a code sample? – Mysticial Dec 18 '11 at 04:27
  • 2
    I don't understand what makes your doubt that. – MK. Dec 18 '11 at 04:33
  • 1
    Then short answer: Yes. It will zero the entire memory region occupied by `ms`. Padding bits and all... – Mysticial Dec 18 '11 at 04:34
  • @MK, I have seen a comment somewhere that "do not memcmp structures even though you had memset those structures before using them". What I thought is if the padding bits are already memset to 0 there wont be any issue for using memcmp later. May be the reference I found is wrong. – Lunar Mushrooms Dec 18 '11 at 04:41
  • 7
    I would think this might be a good idea to not rely on memcmp generally to compare your structures because if you ever where to forget to memset you'd have one nasty hard to find bug on your hands. So unless it has been proven that it is a performance bottle neck, write explicit compare function. Also imagine a situation where you have a char buf[20] and in one struct you set to "aaa" and in another to "bbb" and then you set both to "c". The structs are now logically equal but memcmp will see them as different. – MK. Dec 18 '11 at 04:45
  • @MK, Thanks . Now i got why shouldn't we compare structure even after memset to 0. – Lunar Mushrooms Dec 18 '11 at 04:53

3 Answers3

14

Perhaps worth noting that memset doesn't know anything about your struct (or array, or primitive, or any chunk of memory whatsoever that you happen to unleash it on), so even if it wanted to leave the padding bits intact, it wouldn't even know where they are.

Gravity
  • 2,696
  • 1
  • 20
  • 29
  • 1
    This is not true; all recent compilers know the semantics of `memset` and optimize around this, and the compiler certainly *does* know about where padding is. – saagarjha Sep 06 '20 at 19:01
11

Yes, memset writes a 32 bit value into a contiguous region of memory of a given length starting at the given address. In your case, memset writes the region with (32bit value) 0.

So if you do a memset of length sizeof (your_struct), you should be fine:

memset(&ms, 0, sizeof(struct MyStruct));
jman
  • 11,334
  • 5
  • 39
  • 61
8

If it matters, you're likely doing something unsafe and non-portable.

Yes, the memset call will set any padding bits (or bytes) to 0 -- but there's no guarantee in the language that setting a float object to all-bits-zero will set it to 0.0. The same applies to pointers: all-bits-zero isn't guaranteed to be a null pointer. (In both cases, it happens to be true for most implementations.)

The original ISO C90 or C99 standard didn't even guarantee that all-bits-zero is a valid representation of 0 for integer types; one of the post-C99 Technical Corrigenda added such a guarantee (for integer types only).

For portability, if you want something to be zero, set it explicitly. You can also take advantage of the zero value initialization for static objects and for omitted members in initializers.

A terminological nitpick: "padding bits" are part of the representation of integer types (and usually there are none of them). Padding between struct members is padding bytes.

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631