#program pack() 字节对齐

指令sidt读取IDT结构时,用到了#program pack(push,1)

                                              #program(pop)

学习一下这个知识:

定义struct/class的时候 编译器会把其中的每个成员的存储位置对齐。
对齐原则一般是和该成员大小一致,比如int的就从%4=0的地址开始存储,多余的空间就编译器随便填充了。
然后struct还要填充,直到整个struct的大小是最大成员大小的倍数(VC6.0)——为什么呢?
这样应该是为了保证连续存储的时候下一个struct的最大成员也是对齐的。
此外,编译器还会对struct的存储地址进行对齐。

我实际测试了一下,我发现32bit的gcc在对struct进行填充的时候
如果某成员的大小大于4Bytes(long long, double)的时候,实际上是以4字节对齐的。

如果在程序中指定了
#pragma pack(n)
那么对齐的时候就会把元素的大小和n进行比较,取较小的那个来对齐。

此外:
#pragma pack(push)
#program pack(pop)
可以成对使用,用来保存(push)当前的n和取出(pop)之前的n——当然,这是在编译过程中处理的。

下面是我的一段测试程序:

# include  
# include < string.h> 

struct ta{ 
     unsigned  char a; // 1 Byte 
     unsigned  long  long b; // 8 Byte 
     unsigned  short c; // 2 Byte 
}; 

# pragma pack(2) 
struct tb{ 
     unsigned  char a; // 1 Byte 
     unsigned  long  long b; // 8 Byte 
     unsigned  short c; // 2 Byte 
}; 

void dump( void *t,  int size){ 
     printf("---- @%x size = %2d ----\n", ( int)t, size); 
     for ( int i = 0; i < size; ++i){ 
         printf("%2d: %x\n", i, *(( char*)t+i)); 
    } 
     printf("-------------------\n"); 
} 

int main(){ 
    ta a; 
    memset(&a, 0,  sizeof(ta)); 
    a.a = 0xff; 
    a.b = 0xffffffffffffffffull; 
    a.c = 0xffff; 
    dump(&a,  sizeof(ta)); 

    tb b; 
    memset(&b, 0,  sizeof(tb)); 
    b.a = 0xff; 
    b.b = 0xffffffffffffffffull; 
    b.c = 0xffff; 
    dump(&b,  sizeof(tb)); 
     return 0; 
}

你可能感兴趣的:(C++)