Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Slack byte in C structures

Tags:

c

struct

I know the concept of word boundary whereby computer stores structures using word boundary. I am working on a 64 bit CPU with a 64 bit OS. The value of __WORDSIZE macro in limits.h is 64. So my word boundary is 8 bytes right?

I have two structures:

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

sizeof(struct a) gives 12 as answer. sizeof(int) is 4. sizeof(float) is 4.

For struct b{
char a;
char b;
char c;
char d;
};

sizeof(struct b) is 4.

These outputs suggest the word boundary is 4 bytes. How do I find the word boundary. Is it really equal to sizeof(int) then?

Strangely:

struct c{
char a;
char b;
char c;
char d;
char e;
}

sizeof(struct c) is 5 bytes. Can anyone explain this please.

like image 755
Bruce Avatar asked Feb 23 '23 02:02

Bruce


2 Answers

First of all, __WORDSIZE is not there for you to inspect. You should never use macros (or other names) beginning with __ or _ and a capital letter unless they're specifically documented for your use. It's an internal part of the implementation used by headers, and the implementation is free to remove or rename it in a later version. Other systems may not even have a corresponding macro at all, or may have it by a different name.

With that said, structure alignment has nothing to do with the native "word" size. It has to do with the alignments of the individual elements of the structure.

See my answer to this question:

How does gcc calculate the required space for a structure?

like image 188
R.. GitHub STOP HELPING ICE Avatar answered Feb 25 '23 14:02

R.. GitHub STOP HELPING ICE


In struct a, you have a 4-byte integer, 1 byte char, 3 bytes padding to align the float to a 4-byte boundary, and 4 bytes for the float. On some machines and for some structures, you might have as many as 7 bytes padding between a char and a following double, as in struct f:

struct f
{
    char   a;
    double b;
};

There aren't any alternative sizes for struct b under any circumstances I can think of.

With struct c, the compiler can place successive elements without any padding because none of the elements in the structure need more stringent alignment. If you had:

struct d
{
    short a;
    char  b;
    char  c;
    char  d;
};

it would be reasonable to expect the size to be 6 (if not 8), because the short needs to be aligned on a 2-byte boundary.

struct e
{
    int   a;
    char  b;
};

On many platforms, sizeof(struct e) will be 8 because the structure must be 4-byte aligned.

The macro __WORDSIZE has very little to do with any of this. It isn't a standardized macro.

like image 45
Jonathan Leffler Avatar answered Feb 25 '23 15:02

Jonathan Leffler