Byte alignment in C language and # Use of pragma pack

Source: Internet
Author: User

Default byte alignment of the C compiler (natural)

By default, the C compiler allocates space for each variable or data unit based on its natural limitations.

In the structure, the compiler allocates space for each member of the structure based on its natural alignment condition. Each member is stored in the memory in the declared Order (there may be null bytes inserted between members). The address of the first member is the same as that of the entire structure.

 

The default structure member of the C compiler is "N Bytes alignment", which is the length of the member data type.For example, the natural boundary condition of an int-type member is 4-byte alignment, while that of a double-type structure member is 8-byte alignment. If the starting offset of a Member is not located on the member's "Default natural limitations", add an appropriate number of NULL bytes after the previous section.

 

The default structure of the c compiler has the following natural limitations: the most natural limitations required by all members of the structure.If the sum of the length of each member of the struct is not an integer multiple of the Limit Conditions of the structure as a whole, an empty byte is entered after the last member.

Example 1 (analyze the default byte-to-boundary condition of each member in the structure and the default byte-to-boundary condition of the structure ):

 Struct Test
{
Char x1; // The member x1 is of the char type (its starting address must be 1 byte peer interface), and its offset address is 0.

Char x2; // The member x2 is of the char type (the starting address must be a 1-byte peer interface, and its offset address is 1

Float x3; // The member x3 is of the float type (the starting address must be 4 bytes ). The Compiler fills two blank bytes between x2 and x3, and its offset address is 4

Char x4; // The member x4 is of the char type (its starting address must be 1-byte peer interface), and its offset address is 8
};

In the Test struct, the largest member is flaot x3, because some of the struct's natural boundary conditions are 4-byte alignment. The length of the struct is 12 bytes and the memory layout is 1100, 1111, 1000.

Example 2:

 # Include <stdio. h>
// # Pragma pack (2)
Typedef struct
{
Int aa1; // 4 bytes aligned 1111
Char bb1; // 1 byte alignment 1
Short; // two bytes aligned with 011
Char DD1; // 1 byte alignment 1
} Testlength1;
Int length1 = sizeof (testlength1); // 4-byte alignment, occupied byte 1111 1011 1000, length = 12

Typedef struct
{
Char BB2; // 1 byte alignment 1
Int Aa2; // 4 bytes aligned 01111
Short CC2; // 2 bytes aligned to 11
Char dd2; // 1 byte alignment 1
} Testleng2;
Int leng2's = sizeof (testleng2's); // 4-byte alignment, occupied byte 1011 1111 1000, length = 12


Typedef struct
{
Char bb3; // 1 byte alignment 1
Char DD3; // 1 byte alignment 1
Int aa3; // 4 bytes aligned 001111
Short cc23 // 2 bytes aligned to 11

} Testlength3;
Int length3 = sizeof (testlength3); // 4-byte alignment, occupied byte 1100 1111 1100, length = 12


Typedef struct
{
Char BB4; // 1 byte alignment 1
Char DD4; // 1 byte alignment 1
Short cc4; // 2 bytes aligned to 11
Int aa4; // 4 bytes aligned 1111
} Testlength4;
Int length4 = sizeof (testlength4); // 4 bytes aligned, occupying 1111 bytes, length = 8


Int main (void)
{
Printf ("length1 = % d. \ n", length1 );
Printf ("lengh2 = % d. \ n", leng22 );
Printf ("length3 = % d. \ n", length3 );
Printf ("length4 = % d. \ n", length4 );
Return 0;
}

Change the default peer condition (specify the peer condition)
· With the pseudo command # pragma pack (n), the C compiler will align according to n Bytes.
· Use the pseudo command # pragma pack () to cancel the custom byte alignment.

In this case, the alignment rule is:

1, Data member alignment rules: structure (struct) (or union) data member, the first data member is placed in the position where the offset is 0, in the future, the alignment of each data member is performed according to the value specified by # pragma pack and the smaller value of the data member's length.

2. Overall alignment rules of the structure (or union): After the data members align themselves, the structure (or union) itself also needs to be aligned, alignment is performed according to the value specified by # pragma pack and the smaller value in the maximum data member length of the structure (or union.

Combined with 1 and 2, we can infer that when the n value of # pragma pack is equal to or greater than the length of all data members, the n value will not have any effect.

 

Therefore, when the pseudo command # pragma pack (2) is used, the size of the Test struct is 8, and the memory layout is 11 11 11 10.

Note that when the struct contains a child structure, the Members in the sub-structure are aligned according to the value specified by # pragma pack and the smaller member length in the maximum data member of the sub-structure.Example:

# Pragma pack (8)
Struct s1 {
Short;
Long B;
};

Struct s2 {
Char c;
S1 d;
Long e;
};
# Pragma pack ()

The result of sizeof (s2) is 24. The memory layout of S1 is 1100 1111, and that of S2 is 1000 1100 1111 0000 1111.

Example:

 # Include <stdio. h>
# Pragma pack (2)
Typedef struct
{
Int aa1; // two bytes aligned 1111
Char bb1; // 1 byte alignment 1
Short; // two bytes aligned with 011
Char dd1; // 1 byte alignment 1
} Testlength1;
Int length1 = sizeof (testlength1); // two bytes are aligned, occupying 11 11 11 10 11 10, length = 10

Typedef struct
{
Char bb2; // 1 byte alignment 1
Int aa2; // two bytes aligned 01111
Short cc2; // 2 bytes aligned to 11
Char dd2; // 1 byte alignment 1
} Testleng2;
Int leng2's = sizeof (testleng2's); // two bytes are aligned, occupying 10 11 11 11 10, length = 10


Typedef struct
{
Char bb3; // 1 byte alignment 1
Char dd3; // 1 byte alignment 1
Int aa3; // 2 bytes aligned to 11 11 11
Short cc23 // 2 bytes aligned to 11

} Testlength3;
Int length3 = sizeof (testlength3); // two bytes alignment, occupying 11 11 11 11 11, length = 8


Typedef struct
{
Char bb4; // 1 byte alignment 1
Char dd4; // 1 byte alignment 1
Short cc4; // 2 bytes aligned to 11
Int aa4; // 2 bytes aligned to 11 11 11
} Testlength4;
Int length4 = sizeof (testlength4); // two bytes aligned, occupying 11 11 11 11 11, length = 8


Int main (void)
{
Printf ("length1 = % d. \ n", length1 );
Printf ("lengh2 = % d. \ n", leng22 );
Printf ("length3 = % d. \ n", length3 );
Printf ("length4 = % d. \ n", length4 );
Return 0;
}

In addition, the following method is provided:

· _ Attribute (aligned (n) to align the structure members to the natural boundary of n Bytes. If the length of a member in the structure is greater than n, the maximum member length is used for alignment.

· _ Attribute _ (packed): cancels the optimization alignment of the structure during compilation and alignment according to the actual number of bytes occupied.

The first method above n = 1, 2, 4, 8, 16... is more common.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.