C++ 标准是否对对象的内存布局做保证C/C++ codeclass Mat4f{public:Mat4f(const float *m){*this *reint
C++ 标准是否对对象的内存布局做保证
- C/C++ code
class Mat4f{public: Mat4f(const float *m) { *this = *reinterpret_cast<const Mat4f *>(m); }private: float m_m[4][4];};int main(){ float m[16] = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}; Mat4f mat(m); return 0;}上面的代码能不能保证正确的行为,如果对象没有虚函数、虚继承,是不是可以用类似 *this = *reinterpret_cast<const Mat4f *>(m); 的代码代替类似 memcpy(m_m, m, sizeof(m_m)); 的代码?
[解决办法]
除了隐式类型转换,其他强制的类型转换都丧失了强类型语言的优点,慎用。除非必要,就不要轻易使用。
比如下面的例子就有强制的类型转换,结果是不可靠的。
- C/C++ code
printf("%d", 3/2);
[解决办法]
其实即使POD,标准也没有保证同一的内存映像。
这其实是C/C++是否应该建立ABI的问题,有些专家鼓吹应建立ABI,但我认为这是画蛇添足,不对内存映像作出保证其实是C/C++的语言特性,而C/C++不应放弃这个特性,否则C/C++将不再是C/C++而流于庸俗了。
[解决办法]
[解决办法]
C++标准中没有对对象的内存布局进行定义,由编译器自行调整。简化了编译器的复杂度,增加了编译器的灵活度,可以编译出高效率的程序。常见的优化有字节对齐。
你可以看看下面类的字节内容就知道了,用VC10编译器试试。
- C/C++ code
class A{public: int a; int b; int c; double d;};
[解决办法]
只是第一个非静态成员,可以。
ISO C++11 9.2
20 A pointer to a standard-layout struct object, suitably converted using a reinterpret_cast, points to its initial member (or if that member is a bit-field, then to the unit in which it resides) and vice versa. [ Note:
There might therefore be unnamed padding within a standard-layout struct object, but not at its beginning, as necessary to achieve appropriate alignment. —end note ]
[解决办法]
[解决办法]
[解决办法]
[解决办法]
In a union, at most one of the data members can be active at any time, that is, the value of at most one of
the data members can be stored in a union at any time. [Note:one special guarantee is made in order to
simplify the use of unions:
If a POD-union contains two or more POD-structs that share a common initial sequence, and if the POD-union object currently contains one of these POD-structs, it is permitted to inspect the common initial part
of any of them. Two POD-structs share a common initial sequence if corresponding members have layout-compatible types (and, for bit-fields, the same widths) for a sequence of one or more initial members.
