Alignment of a structure, a tricky issue


Naive me use "sizeof(structure x)" at work and get big issue, make a summary about how the alignment works for a structure.


The most important tip is, different compiler has different strategy for structure alignment.

Test using IAR for ARM/Keil/GCC under Ubuntu/Freescale Codewarrior GCC/Freescale Codewarrior ARM complier/YAGARTO


1. Default alignment

Test code:

#include <stdio.h>  
struct align_test_1  
{  
    char a;  
    short int b;  
};  
  
struct align_test_2  
{  
    char a;  
    short int b;  
    int c;  
};  
  
struct align_test_3  
{  
  double a;  
  char b;  
  int c;  
  short int d;  
};  
  
void main()  
{  
    int i,j,k;  
    i = sizeof(struct align_test_1);  
    j = sizeof(struct align_test_2);  
    k = sizeof(struct align_test_3);  
    printf("the size of struct align_test_1 is %d\n", i);  
    printf("the size of struct align_test_2 is %d\n", j);  
    printf("the size of struct align_test_3 is %d\n", k);  
}  

Test result:

For IAR/Keil/Freescale codewarrior GCC/YAGARTO, result is:

i = 4,

j = 8,

k = 24


For GCC Ubuntu/Freescale Codewarrior ARM complier, result is:

i = 4,

j = 8,

k = 20


Conclusion: 

1) For IAR/Keil/Freescale codewarrior GCC/YAGARTO, the default structure alignment depends on the highest type of its member;

2) For For GCC/Freescale Codewarrior ARM complier, the highest alignment seems to be 4;


How to know what is the alignment for a compiler?

Check official manual is OK, but the manual is so awful to read, so why not just write a short line of code to check it:

struct align_test_1  
{  
    char a;  
    short int b;  
};  
  
struct align_test_2  
{  
    char a;  
    short int b;  
    int c;  
};  
  
struct align_test_3  
{  
  double a;  
  char b;  
  int c;  
  short int d;  
};  
  
void main()  
{  
    int i,j,k;  
    i = __alignof__(struct align_test_1);  
    j = __alignof__(struct align_test_2);  
    k = __alignof__(struct align_test_3 );   
    printf("i = %d\n", i);
    printf("j = %d\n", j);
    printf("k = %d\n", k);
}  

For IAR/Keil/Freescale codewarrior GCC/YAGARTO, result is:

i = 2

j = 4

k = 8

For GCC/ Freescale Codewarrior ARM complier, result is:

i = 2;

j = 4;

k = 4;


2. Increase the alignment

 __attribute__ ((aligned(n)))

Funny thing:

I thought "__attribute__ ((aligned(1)))" would make the alignment to be 1, but it isn't.
I found one explanation for this from gcc official website: 
"The aligned attribute can only increase the alignment"


Test code:

#include <stdio.h>
struct align_test_1 
{ 
    char a; 
    short int b; 
}__attribute__ ((aligned(4))); 

struct align_test_2 
{ 
    char a; 
    short int b; 	
}__attribute__ ((aligned(8))); 

struct align_test_3 
{ 
    char a; 
    short int b; 
    int c;	
}__attribute__ ((aligned(1024))); 

void main() 
{ 
    int i,j,k;    
    i = __alignof__(struct align_test_1);    
    j = __alignof__(struct align_test_2);    
    k = __alignof__(struct align_test_3 );     
    printf("i = %d\n", i);  
    printf("j = %d\n", j);  
    printf("k = %d\n", k); 
}

All compilers except IAR, result is:

i = 4

j = 8

k = 1024


For IAR, error occur when compiling the above code:


I check the IAR help document, it seems that there is no way to increase the alignment of a structure.


3. Decrease the alignment

#pragma pack(n)

#pragma pack()

Test code:

#include <stdio.h>

#pragma pack(1)
struct align_test_1 
{ 
    char a; 
    short int b; 
}; 
#pragma pack()

#pragma pack(1)
struct align_test_2 
{ 
    char a; 
    short int b; 
    int c;	
}; 
#pragma pack()

#pragma pack(2)
struct align_test_3 
{ 
    char a; 
    short int b; 
    int c;	
}; 
#pragma pack()

void main() 
{ 
    int i,j,k;    
    i = __alignof__(struct align_test_1);    
    j = __alignof__(struct align_test_2);    
    k = __alignof__(struct align_test_3 );     
    printf("i = %d\n", i);  
    printf("j = %d\n", j);  
    printf("k = %d\n", k); 
} 

Result for all the compilers mentioned above:

i = 1

j = 1

k = 2


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值