I am using __attribute__((packed)) to avoid struct padding. The below code is working fine, but when I add one more int member inside the struct the compiler pads my struct.
#include <stdio.h>
struct test {
    int x;
    char c1;
    char c2;
    char c3;
    char c4;
    char c5;
    // int d; Pads if I uncomment
} __attribute__((packed)) obj = {50,'X','Y','Z','A','B'}; 
int main ()
{
    struct test *ptr= &obj;
    char *ind = (char *) &obj;
    printf("\nLet's see what is the address of obj %d", ptr);
    printf("\n Size of obj is : %d bytes ", sizeof(obj));
    printf("\nAddress of x is %d", &ptr->x);
    printf("\nAddress of c1 is %d", &ptr->c1);
    printf("\nAddress of c2 is %d", &ptr->c2);
    printf("\nValue  of x is %d", ptr->x);
    printf("\nAddress of x is %c", ptr->c1);
    printf("\nFetching value of c4 through offset %c", *(ind+7));
}
The above code is working as expected and the size of obj is 9 bytes (with padding it was 12 bytes).
However, when I uncomment int d in my struct the code outputs:
Size of obj is : 16 bytes
instead of the expected 13 (9 + 4) bytes.
What's wrong?
In structures there are two types of padding involved. (1) Padding added to make the structure a multiple of a certain number (In your case the size of int) and (2) Padding added to position certain data types at an address divisible by certain number. For example, 4 bytes for int. So in your case while compiler is happy to remove the first type of padding I think it is still forcing the member int d to an address divisible by 4. Since there are 5 chars before d, 3 bytes padding is added to force d to an address divisible by 4.
So try moving the member int d above the chars. Then of course you have to change the offset used in fetching value of c4 through offset. You can even put it right above c5. Then you wouldn't have to change your fetching value of c4 through offset line.  Example:
struct test {
    int x;
    int d;
    char c1;
    char c2;
    char c3;
    char c4;
    char c5;
} __attribute__((packed)) obj = {50,'X','Y','Z','A','B'}; 
OR
struct test {
    int x;
    char c1;
    char c2;
    char c3;
    char c4;
    int d;
    char c5;
} __attribute__((packed)) obj = {50,'X','Y','Z','A','B'}; 
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With