ThP
ThP

Reputation: 2342

Gaps in aligned struct in C

I have a huge struct with different types of members. I know that the members are aligned according to their type.
Is there anyway to figure out where the gaps are?
What I mean is that I am interested to know between which members the complier inserted a gap (and of course what is the gap size).

Upvotes: 2

Views: 1037

Answers (3)

Random832
Random832

Reputation: 39090

It is platform dependent, you can determine it with a small test program using the offsetof macro, or for most Unix systems you can refer to your architecture's System V ABI document.

In general, extra space is inserted immediately before any member that would otherwise be incorrectly aligned, without any reordering, and at the end if it would cause the next structure in an array to be incorrectly aligned.

struct s { short a; int b; };
offsetof(struct s, a) == 0
offsetof(struct s, b) == 4 // for example
sizeof(short) == 2

Gap is two bytes between a and b.

To detect padding at the end of a struct, just look at the size of the struct along with the offset and size of the last element.

struct s2 { int a; short b; };
offsetof(struct s2, b) == 4
sizeof(struct s2) == 8

Upvotes: 5

Serge Ballesta
Serge Ballesta

Reputation: 149185

If you do not want to use the offsetof macro, you can do it the hard way by taking pointers and converting all to char *. Example :

#include <stdio.h>

struct my_struct {
    char c;
    short h;
    char c2;
    long l;
};

void display(FILE *fd) {
    struct my_struct ms;
    int delta1 = (char *)(void *) &ms.h - (char *)(void*) &ms.c;
    int gap1 = delta1 - sizeof(char);
    int delta2 = (char *)(void *) &ms.c2 - (char *)(void*) &ms.h;
    int gap2 = delta2 - sizeof(short);
    int delta3 = (char *)(void *) &ms.l - (char *)(void*) &ms.c2;
    int gap3 = delta3 - sizeof(char);
    int gap4 = sizeof(ms) -sizeof(long) - ((char *)(void *) &ms.l - (char *)(void*) &ms);
    fprintf(fd, "char to short : %d - short to char %d - char to long %d - struct to struct : %d\n",
        gap1, gap2, gap3, gap4);
}
int main() {
    display(stderr);
}

gives :

char to short : 1 - short to char 0 - char to long 3 - struct to struct : 0

Upvotes: 0

2501
2501

Reputation: 25753

Use offsetof() defined in stddef.h

struct my
{
    float f ;
    double d ;
} ;

This gets padding in between f and d:

size_t p = offsetof(struct my , d) - ( offsetof(struct my , f) + sizeof(float) );

Do this for every member of the struct.

Upvotes: 4

Related Questions