「Inside the C++ Object Model」では、0 へのポインターと最初のデータ メンバーへのポインターを区別するために、クラス内のデータ メンバーのオフセットは常に実際のオフセットよりも 1 大きいと述べています。次に例を示します。
class Point3d {
public:
virtual ~Point3d();
public:
static Point3d origin;
float x, y, z;
};
//to be used after, ignore it for the first question
int main(void) {
/*cout << "&Point3d::x = " << &Point3d::x << endl;
cout << "&Point3d::y = " << &Point3d::y << endl;
cout << "&Point3d::z = " << &Point3d::z << endl;*/
printf("&Point3d::x = %p\n", &Point3d::x);
printf("&Point3d::y = %p\n", &Point3d::y);
printf("&Point3d::z = %p\n", &Point3d::z);
getchar();
}
したがって、以下の 2 つのポインターを区別するために、データ メンバーのオフセットは常に 1 つ多くなります。
float Point3d::*p1 = 0;
float Point3d::*p2 = &Point3d::x;
上記のメイン関数は、この引数を検証するためにメンバーのオフセットを取得しようとするもので、次のように出力されるはずです: 5、9、13 (先頭の 4 バイトの vptr を考慮してください)。ただし、 MS Visual Studio 2012では、出力は次のようになります。
&Point3d::x = 00000004
&Point3d::y = 00000008
&Point3d::z = 0000000C
質問: MS C++ コンパイラは、このメカニズムを防ぐために何らかの最適化または何かを行いましたか?