Guy Avraham
Guy Avraham

Reputation: 3690

Struct members ordering advantages in C

I know that in C, the order of the struct members is the order in which they are declared plus (usually, unless stated otherwise) padding might occur, leading to the two first structs I created with their respective size:

struct MyStructV1
{
    int a;
    char c;
    int b;  
};

printf("size of MyStructV1 is:%lu \n",sizeof(struct MyStructV1)); // prints 12

struct MyStructV1Packed
{
    int a;
    char c;
    int b;
}__attribute__((__packed__));;

printf("size of MyStructV1Packed is:%lu \n",sizeof(struct MyStructV1Packed)); // prints 9 

So far, so good.

My question is, then, does the following declaration of "the unpacked" version of MyStructV2 has any benefits/advantages over the first version of MyStructV1?

struct MyStructV2
{
    int a;
    int b;
    char c;
};

printf("size of MyStructV2 is:%lu \n",sizeof(struct MyStructV2)); // prints 12 as well 

Note that now the order of the members has changes (b is declared before c).

I'm referring to memory access "costs" or cycles needs to be done in order to read/write the struct members and/or any other considerations that are relevant ?

Is it compiler/architecture dependent (if at all)?

Upvotes: 2

Views: 675

Answers (3)

Luca_65
Luca_65

Reputation: 137

If char is smaller than int (usually it is so), the structure MyStructV1 CAN be smaller than MyStructV2.

Depending on the environment (architecture and compiler options) struct MyStructV1 can envelop a pad or can misalign b. Depending on the architecture, if b is misaligned loading it can require more CPU clocks.

Moreover, depending on the architecture, reading a can load something more to be immediately available, if there are paddings this benefit is reduced or lost.

Upvotes: 1

0___________
0___________

Reputation: 67546

That is more interesting and of course ordering matters.

struct aaa1{
    char a;
    char a1;
    int b;
};

struct aaa2{
    char a;
    char a1;
    char a2;
    int b;
};

struct aaa3{
    char a;
    char a1;
    char a2;
    char a3;
    int b;
};

struct aaa4{
    char a1;
    char a2;
    char a3;
    int b;
    char a;
};

int main(void) {

struct aaa5{
    char a;
    int b;
    char a1;
};


    printf("%zu %zu %zu %zu %zu %zu\n", sizeof(struct aaa), sizeof(struct aaa1), sizeof(struct aaa2), sizeof(struct aaa3), sizeof(struct aaa4), sizeof(struct aaa5));

Output : 8 8 8 8 12 12

Upvotes: -1

Barmar
Barmar

Reputation: 781058

There should be little or no difference between the first and last versions. In both structs, the int members are aligned on word boundaries, so they can be read from memory efficiently. The only difference between them is that the padding is between c and b in MyStructV1, and at the end of the structure in MyStructV2. But there is no execution overhead due to padding; accessing struct members is done simply by adding a known offset to the address of the beginning of the struct. In MyStructV1 the offset of b is 8, in MyStructV2 it's 4.

Upvotes: 4

Related Questions