C语言内存对齐详解(3)
接上一篇:C语言内存对齐详解(2)
在minix的stdarg.h文件中,定义了如下一个宏:
/* Amount of space required in an argument list for an arg of type TYPE. * TYPE may alternatively be an expression whose type is used. */ #define __va_rounded_size(TYPE) \ (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))
从注释以及宏的名字可以看出是有关内存对齐方面的作用。根据前两篇关于C语言内存对齐方面的理论可知
n字节对齐就是说变量存放的起始地址的偏移量有两种情况:
第一、如果n大于等于该变量所占用的字节数,那么偏移量必须满足默认的对齐方式(各成员变量存放的起始地址相对于结构的起始地址的偏移量必须为该变量的类型所占用的字节数的倍数);
第二、如果n小于该变量的类型所占用的字节数,那么偏移量为n的倍数,不用满足默认的对齐方式。
此时n = 4,对于sizeof(TYPE)一定为自然数,sizeof(int) - 1 = 3
sizeof(TYPE)只可能出现如下两种情况:
(1) 当sizeof(TYPE) >= 4,偏移量 = (sizeof(TYPE)/4)*4
(2) 当sizeof(TYPE) < 4,偏移量 = 4
此时sizeof(TYPE) = 1 or 2 or 3,而(sizeof(TYPE) + 3) / 4 = 1
为了将上述两种情况统一,偏移量 = ((sizeof(TYPE) + 3) / 4) * 4
在有的源代码中,将内存对齐宏__va_rounded_size通过位操作来实现,代码如下:
#define __va_rounded_size(TYPE) \ ((sizeof(TYPE)+sizeof(int)-1)&~(sizeof(int)-1))
由于 ~(sizeof(int) – 1) ) = ~(4-1)=~(00000011B)=11111100B
(sizeof(TYPE) + sizeof(int) – 1)就是将大于4m但小于等于4(m+1)的数提高到大于等于4(m+1)但小于4(m+2),这样再& ~(sizeof(int) – 1) )后就正好将原长度补齐到4的倍数了。