9.3.1 排列方式和补全(padding )
在C++(www.cppentry.com)中,许多类型都有排列方式限制,考虑下面的代码:
- char x[sizeof(int)];
- int* p=(int*)x;
- *p = 0;
如果数组x并不能得到int类型的内存空间大小,那么第3条语句(*p = 0)可能会导致不确定的行为(程序可能会中止 )。
为了可以得到最大的可移植性,代码就不应该依赖于对象内部的布局,因为语言定义根本就没有保证这种布局不会发生改变。例如,下面的代码
- int i;
- char* p = (char*)&i;
并不能保证p肯定会指向i中的最低字节(或任何其他特定字节)。
现在考虑下面的代码:
- static union{
- int i;
- int bits:32;
- };
- bit ^= 1;
即使我们知道上面的代码将会在int类型为32位的机器上运行,也不能保证赋值语句将会把i的最低位(或者任何其他特殊位)置位。
不仅如此,可移植代码还不能依赖于类对象的内部补全(padding)机制。例如,考虑下面代码:
- struct X {
- cnar c1;
- char c2;
- };
- int main() {
- X x;
- char* p = &x.c1;
- ++p;
- //...
- }
我们并不能保证当p执行自增之后,它就会指向x.c2。
试图重叠不同的结构体也会导致许多可移植性问题。考虑下面的代码,它试图重叠结构体X和Y:
- struct X{
- char c1;
- char c2;
- };
- struct Y{
- int bits: 8;
- char c2;
- };
- int main() {
- X x;
- Y* y = (Y*)&x;
- y->c2 = 0;
- //...
- }
即使我们知道这段代码将会在char类型为8位的机器上运行,我们也不能保证y->c2赋值语句可以清除x中c2域的值 。