コンパイラの位置合わせのメカニズム--C++クラスの大きさを求める問題から言います


32ビットの下でsizeof(a)はいくらですか?
class A
{
        int i;
        union U
                {
                        char buff[13];
                        int i;
                }u;
        void foo(){}
        typedef char* (*f)(void*);
        enum{red,green,blue}color;

}a;
の結果は24であり,int iが4バイト,union U uが16バイト,列挙値colorが4バイトであった.
難点はunionの大きさに集中し、最大は16ではなく13であるべきだ.
16はどのように来て、位置合わせのメカニズムで、巧みにこの位置合わせの上で、もし問題の中で示すように、それではその大きさは16です
        union U
                {
                        char buff[13];
                        int i;
                }u;

そのintがなければ、いくらになりますか?
        union U
                {
                        char buff[13];
                }u;
実はこの時は13で、この位置合わせはintに出会ってから現れたのが見えます.
しかし、実はこの結果は可変で、上のはすべてgcc/g++が自動的に出た結果で、実は手動で変えることができます.#pragma pack(1)で1に整列すると、結果として
#pragma pack(1)
class A
{
        int i;
        union U
                {
                        char buff[13];
                        int i;
                }u;

       void foo(){}
       typedef char* (*f)(void*);
       enum{red,green,blue}color;

}a;

そうすると、結果は24ではなく21になります.
結論は、同じ連合体(構造体も実は同じ)内では、charは本来1整列であり、intに触れると4整列となり、テスト(32ビット、g++/gcc)、doubleも4整列であり、shortは2整列であり、いずれもその幅に従って変化する.この「遭遇」は1つの構造体または連合体体内で前後を問わず、先にintするか後intするか、最後にsizeof()の結果は同じである.
しかし、pragma packは前後に分かれており、即時に有効になり、いつ設定され、その後はすべて設定された値です.次のように
class A
{
        int i;
        union U
                {
                        char buff[13];
                        int i;
                }u;
#pragma pack(1)
        char buff[13];
        void foo(){}
        typedef char* (*f)(void*);
        enum{red,green,blue}color;

}a;
sizeof(a)の結果は37で、後ろのこのbuff[13]は1揃えで、前のあのbuff[13]は依然として4揃えです!!!
だから、その問題は厳密ではありません.彼はmain付きのプログラム全体ではなく、一部しか示していません.もし本当に大きな工事の下に置いておけば、事前にアクティブに設定した位置合わせ値があれば、結果は違います(packパラメータも2か4です).
最後に、カスタマイズが完了したら、#pragma pack()が後のクラス定義に影響を与えないようにデフォルト値を復元することを忘れないでください.
PS:コンパイラのパーソナライズされたものは多く、言語そのものではありません.例えば、同じ空の構造体と連合体で、g++でzieof()を見ると結果は1ですが、gccでは0です.コンパイラによっては、それが空であることを注意するためにコンパイルされない場合があります.しかし、空でも空の用途があり、メモリが占有されています.stub(杭)