4

I have a struct such as

typedef struct
{
    int a;  // Let's say this ends up being 4 bytes
    int b;  // 4 bytes
    char text[10]; // 10 bytes
} blah_t;

static blah_t myvar;
  1. Suppose the sum of fields’ sizes is 18 bytes in blah_t, but sizeof(blah_t) is 20 due to padding.
  2. The myvar is static, therefore it will be zero initialized.

Question:

  1. Are padding bytes 19 and 20 guaranteed to be 0 for a static variable? If not, I would need to do memset(&myvar, 0, sizeof(blah_t)) for any memcmp of the struct to be valid – even for a static variable.
  2. What about calloc(1, sizeof(blah_t))? Are bytes 19 and 20 guaranteed to be zero? I believe this is the case.
Palec
  • 12,743
  • 8
  • 69
  • 138
B. Nadolson
  • 2,988
  • 2
  • 20
  • 27

3 Answers3

5

From ISO C99 standard: "When a value is stored in an object of structure or union type, including in a member object, the bytes of the object representation that correspond to any padding bytes take unspecified values."

Looking further, this appears to discuss some additional issues: Comparing structures in C vs C++

EDIT: not a duplicate of this question per se, but many common issues with detailed responses.

Community
  • 1
  • 1
Randy Howard
  • 2,165
  • 16
  • 26
  • Good to quote the standard; can you give 'chapter and verse' (which section, which paragraph)? In C2011 (ISO/IEC 9899:2011), it is in §6.2.6 Representations of types, and sub-section §6.2.6.1 General, para 6. – Jonathan Leffler Mar 13 '13 at 00:09
  • Good point, I meant to and left it out. 6.2.6.1 Representations of types, paragraph 6. – Randy Howard Mar 13 '13 at 00:12
  • I don't see any duplication with the C++ question you mention. C++ classes are a different animal. What I'm hoping to find out ... if somewhere in the specification it describes how static variables are initialized for this particular case. – B. Nadolson Mar 13 '13 at 00:14
  • 1
    It explicitly says that padding values have unspecified values, so you can't really trust memcmp() to "do the right thing" portably. – Randy Howard Mar 13 '13 at 00:19
  • "In both cases, program startup occurs when a designated C function is called by the execution environment. All objects with static storage duration shall be initialized n a designated C function is called by the execution environment. All objects with static storage duration shall be initialized (set to their initial values) before program startup. The manner and timing of such initialization are otherwise unspecified. << So it would seem that padding even for a static struct is undefined. – B. Nadolson Mar 13 '13 at 00:47
  • 2
    This answer could be updated for C11 changes. The padding bits are set to zero when a static variable is not initialized explicitly. I [added an answer](https://stackoverflow.com/questions/15374606/c-struct-padding-on-initialization/57501386#57501386) – afk Aug 14 '19 at 20:13
2

Randy Howard's accepted answer isn't quite accurate anymore with C11.

Are padding bytes 19 and 20 guaranteed to be 0 for a static variable?

  1. In C11, yes, the padding bits are set to zero when a static variable is not initialized explicitly. C11 Standard, Subclause 6.7.9, paragraph 10:

. . . If an object that has static or thread storage duration is not initialized explicitly, then: . . . if it is an aggregate, every member is initialized (recursively) according to these rules, and any padding is initialized to zero bits . . .

  1. Yes, calloc will zero the entire sizeof (including the padding) of the structure.

Other useful and related links:

afk
  • 358
  • 2
  • 11
0

Padding bytes 19 and 20. Are these guaranteed to be 0 for a static variable?

See Randy Howard's answer.

What about calloc(1, sizeof(blah_t) )? Are bytes 19/20 guaranteed to be zero?

Yes. calloc zeros the memory.

Out of curiousity, I'm wondering why it is you care about padding. Portable code shouldn't have to bother with any aspect of representation (padding, endianness, etc).

autistic
  • 1
  • 3
  • 35
  • 80
  • I want to memcmp a static struct versus a struct that has been allocated via calloc. I'm aware the behavior of padding is undefined when it comes to storage, but a statically allocated struct may or may not be considered "storage" in specification. Very technical distinction I'm looking for, yes. – B. Nadolson Mar 13 '13 at 00:44
  • doesn't matter for portability, but can matter for security. Information can be leaked from the stack for automatically allocated variables whose padding was unintialized. – Nick Desaulniers Dec 06 '16 at 21:15