请问各位大侠:
_declspec(align(32))
struct D{
   int a;
   short b;
   int c;
   char d;
}
这个结构中成员是如何排列的,如何对齐的,结构总尺寸是多少?#pragma pack(4)
struct D{
   int a;
   short b;
 _declspec(align(16))
   double val;
   int c;
   char d;
}
这个结构中成员是如何排列的,如何对齐的,结构总尺寸是多少?

解决方案 »

  1.   

    用offsetof可以知道元素的偏移位置
      

  2.   

    align   
      Microsoft   Specific   
      __declspec(align(#))   declarator   
      Use   __declspec(align(#))   to   precisely   control   the   alignment   of   global   data.   By   aligning   frequently   used   data   to   the   cache   line   size   of   a   specific   processor,   you   improve   cache   performance.   For   example,   if   you   define   a   structure   whose   size   is   less   than   32   bytes,   you   may   want   to   align   it   to   32   bytes   to   ensure   that   objects   of   that   structure   type   are   efficiently   cached.   
        
      #   is   the   alignment   value.   Valid   entries   are   powers   of   two   from   1   to   8192   (bytes).   For   example,   2,   4,   8,   16,   32,   or   64.   declarator   is   the   global   data   that   you   are   declaring   as   aligned.   
        
      You   can   use   __declspec(align(   #   ))   when   you   define   a   struct,   union,   or   class,   or   when   you   declare   a   variable.   
        
      Without   __declspec(align(   #   )),   Visual   C++   aligns   data   on   natural   boundaries   based   on   the   size   of   the   data,   for   example   4-byte   integers   on   4-byte   boundaries,   and   8-byte   doubles   on   8-byte   boundaries.   Data   in   classes   or   structures   is   aligned   within   the   class   or   structure   at   the   minimum   of   its   natural   alignment   and   the   current   packing   setting   (from   #pragma   pack   or   the   /Zp   compiler   option).   
        
      You   cannot   specify   alignment   for   stack   variables.   
        
      For   example:   
        
      __declspec(align(32))   struct   Str1   
      {   
          int   a,   b,   c,   d,   e;   
      };   
        
      This   type   now   has   a   32-byte   alignment   attribute,   meaning   that   all   instances   must   start   on   a   32-byte   boundary.   Note   that   sizeof(struct   Str1)   is   equal   to   32   to   support   creation   of   aligned   array   members   using   code   like   malloc(n   *   sizeof(struct   Str1)).   Additional   structure   types   declared   with   this   type   as   a   member   preserve   this   type’s   alignment   attribute.   That   is,   any   structure   with   Str1   as   an   element   will   have   an   alignment   attribute   of   at   least   32.   
        
      The   sizeof   value   for   any   structure   is   the   offset   of   the   final   member,   plus   that   member’s   size,   rounded   up   to   the   nearest   multiple   of   the   largest   member   alignment   value   or   the   whole   structure   alignment   value,   whichever   is   greater.     
        
      See   Also   
      __alignof   
        
      Align   Examples   
      The   following   examples   show   how   __declspec(align(   #   ))   affects   the   size   and   alignment   of   data   structures.   The   examples   assume   the   following   definitions:   
        
      #define   CACHE_LINE     32   
      #define   CACHE_ALIGN   __declspec(align(CACHE_LINE))   
        
      In   the   following   example,   the   S1   structure   is   defined   with   __declspec(align(32)).   All   uses   of   S1,   whether   for   a   variable   definition   or   other   type   declarations,   ensure   that   this   structure   data   is   32-byte   aligned.   sizeof(struct   S1)   returns   32,   and   S1   has   16   padding   bytes   following   the   16   bytes   required   to   hold   the   four   integers.   Each   int   member   requires   four-byte   alignment,   but   the   alignment   of   the   structure   itself   is   declared   to   be   32,   so   the   overall   alignment   is   32.   
        
      struct   CACHE_ALIGN   S1     //   cache   align   all   instances   of   S1   
      {   
              int   a,   b,   c,   d;   
      };   
      struct   S1   s1;       //   s1   is   32-byte   cache   aligned   
        
      In   the   following   example,   sizeof(struct   S2)   will   return   16,   which   is   exactly   the   sum   of   the   member   sizes,   because   that   happens   to   be   a   multiple   of   the   largest   alignment   requirement   (a   multiple   of   8).   
        
      __declspec(align(8))   struct   S2   
      {   
              int   a,   b,   c,   d;   
      };   
        
      In   the   following   example,   sizeof(struct   S3)   returns   64.   
        
      struct   S3   
      {   
          struct   S1   s1;     //   S3   inherits   cache   alignment   requirement   
                              //   from   S1   declaration   
          int   a;             //   a   is   now   cache   aligned   because   of   s1   
                              //   28   bytes   of   trailing   padding   
      };   
        
      In   the   following   example,   note   that   a   has   only   the   alignment   of   natural   type;   in   this   case,   4   bytes.   However,   S1   must   be   32-byte   aligned.   Twenty-eight   bytes   of   padding   follow   a,   such   that   s1   starts   at   offset   32.   S4   then   inherits   the   alignment   requirement   of   S1,   since   it   is   the   largest   alignment   requirement   in   the   structure.   sizeof(struct   S4)   returns   64.   
        
      struct   S4   
      {   
              int   a;   
              //   28   bytes   padding   
              struct   S1   s1;         //   S4   inherits   cache   alignment   requirement   of   S1   
      };   
        
      The   following   three   variable   declarations   also   use   __declspec(align(   #   )).   In   each   case,   the   variable   must   be   32-byte   aligned.   In   the   case   of   the   array,   the   base   address   of   the   array   is   32-byte   aligned,   not   each   array   member.   The   sizeof   value   for   each   array   member   is   not   affected   by   the   use   of   __declspec(align(   #   )).   
        
      CACHE_ALIGN   int   i;   
      CACHE_ALIGN   int   array[128];   
      CACHE_ALIGN   struct   s2   s;   
        
      To   align   each   individual   member   of   an   array,   code   such   as   the   following   should   be   used:   
        
      typedef   CACHE_ALIGN   struct   {   int   a;   }   S5;   
      S5   array[10];   
        
      In   the   following   example,   note   that   aligning   the   structure   itself   and   aligning   the   first   element   are   identical:   
        
      CACHE_ALIGN   struct   S6   
      {   
              int   a;   
              int   b;   
      };   
        
      struct   S7   
      {   
            CACHE_ALIGN   int   a;   
                                    int   b;   
      };   
        
      S6   and   S7   have   identical   alignment,   allocation,   and   size   characteristics.   
        
      Defining   New   Types   with   __declspec(align(#))   
      You   can   define   a   type   with   an   alignment   characteristic.   
        
      For   example,   you   can   define   a   struct   with   an   alignment   value   as   follows:   
        
      struct   aType   {int   a;   int   b;};   
      typedef   __declspec(align(32))   struct   aType   bType;   
        
      Now,   aType   and   bType   are   the   same   size   (8   bytes)   but   variables   of   type   bType   will   be   32-byte   aligned.   
        
      Aligning   Data   in   Thread   Local   Storage   
      Static   thread-local   storage   created   via   the   __declspec(thread)   attribute,   and   put   in   the   thread-local   storage   (.tls)   section   in   the   image,   works   for   alignment   exactly   like   normal   static   data.   The   operating   system   creates   TLS   data   by   allocating   data   the   size   of   the   .tls   section   and   respecting   the   .tls   section   alignment   attribute.   
        
      The   following   example   shows   various   ways   to   place   aligned   data   into   thread   local   storage,   
        
      //   put   an   aligned   integer   in   TLS   
      __declspec(thread)   __declspec(align(32))   int   a;       
        
      //   define   an   aligned   structure   and   put   a   variable   of   the   struct   type   
      //   into   TLS   
      __declspec(thread)   __declspec(align(32))   struct   F1   {   int   a;   int   b;   }   a;   
        
      //   create   an   aligned   structure   
      struct   CACHE_ALIGN   S9   
      {   
              int   a;   
              int   b;   
      };   
      //   put   a   variable   of   the   structure   type   into   TLS   
      __declspec(thread)   struct   S9   a;   
        
      How   align   Works   with   Data   Packing   
      The   /Zp   compiler   option   and   the   pack   pragma   have   the   effect   of   packing   data   for   structure   and   union   members.   This   example   shows   how   /Zp   and   __declspec(align(   #   ))   work   together:   
        
      struct   S   
      {   
          char   a;   
          short   b;   
          double   c;   
          CACHE_ALIGN   double   d;   
          char   e;   
          double   f;   
      };   
        
      The   following   table   lists   the   offset   of   each   member   under   a   variety   of   /Zp   (or   #pragma   pack)   values,   showing   how   the   two   interact.   
        
      variable   /Zp1   /Zp2   /Zp4   /Zp8     
      a   0   0   0   0     
      b   1   2   2   2     
      c   3   4   4   8     
      d   32   32   32   32     
      e   40   40   40   40     
      f   41   42   44   48     
      sizeof(S)   64   64   64   64     
        
        
      Thus,   the   offset   of   an   object   is   based   on   the   offset   of   the   previous   object   and   the   current   packing   setting,   unless   the   object   has   a   __declspec(align(   #   ))   attribute,   in   which   case   the   alignment   is   based   on   the   offset   of   the   previous   object   and   the   __declspec(align(   #   ))   value   for   the   object.   
        
      END   Microsoft   Specific   
      Built   on   Thursday,   May   11,   2000