0

We know that for alignment reason, a struct can have internal padding bytes.

How can I fill all padding bytes of a non-compact struct with a specific value? In other word, consider the following code segment:

struct Foo; // Is that possible to implement pad_Foo() function? If Yes, How? void pad_Foo(struct Foo *pFoo_x, char pad_byte); void bar(struct Foo *pFoo_x, int fd, char pad_byte) { // reading in *pFoo_x from a file. // It may get some garbage padding bytes. read(fd, pFoo_x, sizeof(struct Foo)); pad_Foo(&x, pad_byte); } 

Is it possible to implement pad_Foo() function, and if the answer is yes, how?

5
  • You do not have any control over the padding bytes in a struct other than to issue a #pragma pack to minimize or eliminate it. Other than that type of influence, the rest is up to the compiler. Commented Mar 19, 2019 at 8:25
  • 1
    Why would you want to do that? (BTW: the answer is no) Commented Mar 19, 2019 at 8:29
  • 2
    You could calloc(sizeof(struct foo), pad_byte) and then set your fields accordingly Commented Mar 19, 2019 at 8:33
  • 2
    @TheophileDano Well, actually not. From the standard: "51) Thus, for example, structure assignment need not copy any padding bits." Commented Mar 19, 2019 at 8:38
  • 2
    The only solution is to memset the structure before first use. Then fill the members. Commented Mar 19, 2019 at 9:29

1 Answer 1

1

Is it possible to implement pad_Foo() function

As standard compliant code the answer is no

From C11 draft n1570, 6.2.6 Representation of types:

6 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. 51)

and

51) Thus, for example, structure assignment need not copy any padding bits.

So the standard clearly says: The value of padding can not be controlled.

On a particular system (platform, os, compiler) it may be possible. As an example from my system:

# include <stdio.h> # include <string.h> struct s { char c; int n; }; void dump_struct(struct s * p) { unsigned char * u = (unsigned char *)p; for (size_t i=0; i < sizeof *p; ++i) printf("%02x ", u[i]); printf("\n"); } int main(){ printf("sizeof(struct s)=%zu sizeof(char)=%zu sizeof(int)=%zu padding=%zu\n", sizeof(struct s), sizeof(char), sizeof(int), sizeof(struct s) - sizeof(char) - sizeof(int)); struct s sa; memset(&sa, 'A', sizeof sa); sa.c = '8'; sa.n = 42; dump_struct(&sa); struct s sb; memset(&sb, 'B', sizeof sa); sb.c = '8'; sb.n = 42; dump_struct(&sb); } 

Output:

sizeof(struct s)=8 sizeof(char)=1 sizeof(int)=4 padding=3 38 41 41 41 2a 00 00 00 38 42 42 42 2a 00 00 00 ^^^^^^^^ notice 

So on my system the memset did write the padding bytes but on other systems you may see different behavior.

Adding code like this to main:

 unsigned char * u = (unsigned char *)&sb.c; u += sizeof sb.c; while(u < (unsigned char *)&sb.n) { *u = 'C'; ++u; } dump_struct(&sb); 

will print the extra line:

38 43 43 43 2a 00 00 00 

So again - on my specific system - the padding was changed.

Sign up to request clarification or add additional context in comments.

1 Comment

on any RAM instance of the struct, you can ALWAYS call memset() to initialize the memory before setting the individual fields within the struct

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.