• #pragma pack, _ _packed


    The #pragma pack directive modifies the current alignment rule for members of structures following the directive.

    The #pragma pack directive modifies the current alignment rule for only the members of structures whose declarations follow the directive. 

    It does not affect the alignment of the structure directly, but by affecting the alignment of the members of the structure,
    it may affect the alignment of the overall structure according to the alignment rule.

    The #pragma pack directive cannot increase the alignment of a member, but rather can decrease the alignment.
    For example, for a member with data type of integer (int), a #pragma pack(2) directive would cause that member to be packed
    in the structure on a 2-byte boundary, while a #pragma pack(4) directive would have no effect.

    The #pragma pack directive is stack based. All pack values are pushed onto a stack as the source code is parsed. The value at the top of the current pragma pack stack is the value used to pack members of all subsequent structures within the scope of the current alignment rule.

    #pragma pack stack is associated with the current element in the alignment rule stack.
    Alignment rules are specified with the -qalign compiler option or with the #pragma options align directive.
    If a new alignment rule is created, a new #pragma pack stack is created.
    If the current alignment rule is popped off the alignment rule stack, the current #pragma pack stack is emptied and
    the previous #pragma pack stack is restored. Stack operations (pushing and popping pack settings) affect only the current #pragma pack stack.

    The #pragma pack directive causes bitfields to cross bitfield container boundaries.

    Examples

    1. In the code shown below, the structure S2 will have its members packed to 1-byte, but structure S1 will not be affected. This is because the declaration for S1 began before the pragma directive. However, since the declaration for S2 began after the pragma directive, it is affected.

      struct s_t1 {
          char a;    
          int b;
          #pragma pack(1)
          struct s_t2 {    
                  char x;
                  int y;
          } S2;
          char c;
          int b;
      } S1;
    2. This example shows how a #pragma pack directive can affect the size and mapping of a structure:
      struct s_t {
          char a;
          int b;
          short c;
          int d;
      }S;
       
      Default mapping:With #pragma pack(1):
      sizeof S = 16 sizeof S = 11
      offsetof a = 0 offsetof a = 0
      offsetof b = 4 offsetof b = 1
      offsetof c = 8 offsetof c = 5
      offsetof d = 12 offsetof d = 7
      align of a = 1 align of a = 1
      align of b = 4 align of b = 1
      align of c = 2 align of c = 1
      align of d = 4 align of d = 1
    #pragma pack(n)
    #pragma pack()
    #pragma pack({push|pop}[,name] [,n])
     
    #pragma pack(n)
    #pragma pack()
    #pragma pack({push|pop}[,name] [,n])
    Parameters
     
     
    n
    Sets an optional structure alignment; one of: 1, 2, 4, 8, or 16
    Empty list
    Restores the structure alignment to default
    push
    Sets a temporary structure alignment
    pop
    Restores the structure alignment from a temporarily pushed alignment
    name
    An optional pushed or popped alignment label
     

    Description

    Use this pragma directive to specify the maximum alignment of struct and union members.

    The #pragma pack directive affects declarations of structures following the pragma directive to the next #pragma pack
    or the end of the compilation unit.

    Note:

    This can result in significantly larger and slower code when accessing members of the structure.
    Use either __packed or #pragma pack to relax the alignment restrictions for a type and the objects defined using that type.
    Mixing __packed and #pragma pack might lead to unexpected behavior.

    Description
    Use the __packed keyword to decrease the data type alignment to 1.
    __packed can be used for two purposes:

    When used with a struct or union type definition, the maximum alignment of members of that struct or union is set to 1,
    to eliminate any gaps between the members. The type of each members also receives the __packed type attribute.

    When used with any other type, the resulting type is the same as the type without the __packed type attribute,
    but with an alignment of 1. Types that already have an alignment of 1 are not affected by the __packed type attribute.

    A normal pointer can be implicitly converted to a pointer to __packed, but the reverse conversion requires a cast.

    Note:
    Accessing data types at other alignments than their natural alignment can result in code that is significantly larger and slower.
    Use either __packed or #pragma pack to relax the alignment restrictions for a type and the objects defined using that type.
    Mixing __packed and #pragma pack might lead to unexpected behavior.

    Example

    __packed struct X
    {
      char ch;
      int i;
    };
    /* No pad bytes */
    
    void Foo( struct X * xp ) /* No need for __packed here */
    {
      int * p1 = &xp->i;/* Error:"int *">"int __packed *" */
      int __packed * p2 = &xp->i; /* OK */
      char * p2 = &xp->ch; /* OK, char not affected */
    }
     

  • 相关阅读:
    @Order
    uri和url , 以及末尾加不加 '/'
    windows删除右键新建多余选项
    Typora 指南
    常见状态码/HttpStatusCode
    final 修饰符
    4. shiro-整合redis
    springboot 整合mybatis 一级缓存失效
    springboot查看具体访问的url片段
    JavaSE:NIO
  • 原文地址:https://www.cnblogs.com/shangdawei/p/3118751.html
Copyright © 2020-2023  润新知