It is a 9CBS on an article, very much, summarizes the problem, find some information, combines the knowledge point, and calculate a collection of resources.
Disclaimer: Just for your convenience of learning :)
The first is from http://blog.9cbs.net/wenddy112/Articles/300583.aspx << One problem on the byte alignment of the C compiler by #pragma Pack (n):
For the following structure
Struct Test
{
Char x1;
Short x2;
Float x3;
Char x4;
}
What is the spatial distribution of each member of the structure?
Interpretation in the article:
The first member X1 of the structure, its offset address is 0, occupying the first byte. The second member X2 is a short type, and its start address must be 2 bytes of theoretical, so the compiler fills an empty byte between X2 and X1. The third member X3 and the fourth member X4 of the structure are just on its natural parallel address, and there is no additional padding bytes in front of them. In the TEST structure, the member X3 requires 4-byte alignment, which is the maximum parallel unit required in all members of the structure, so the natural relationship condition of the TEST structure is 4 bytes, and the compiler is filled in the member X4. 3 Empty byte. The entire structure is occupied by 12 bytes.
At the same time, the default byte alignment of changing the C compiler is illustrated: In the default, the C compiler is allocated to all variables or data units according to their natural peer condition. Generally, the default relationship condition can be changed by the following method:
· Use pseudo-instructions #pragma pack (n), and the C compiler will be aligned according to n bytes.
· Use pseudo-instruction #pragma pack () to cancel the custom byte alignment.
In addition, there is a way in the following:
· __Attribute ((aligned (n))), allowing the active structural members to align in the N-byte natural boundary. If the length of the member in the structure is greater than n, it is aligned according to the length of the biggest member.
· __Attribute__ ((packed)), the cancellation structure is aligned in the compilation process, and is aligned according to the actual number of bytes.
The above N = 1, 2, 4, 8, 16 ... is more common.
The following is a problem proposed on 9CBS (original << Intel and Microsoft and interview questions at the same time: http://community.9cbs.net/Expert/topicView3.asp? Id = 3804035)
---------------------------------------
#pragma Pack (8)
Struct s1 {
Short a;
Long B;
}
Struct s2 {
Char C;
S1 D;
Long long e;
}
#pragma pack ()
ask
1.sizeof (s2) =?
2. Twically the C will be empty after a few bytes next to D?
---------------------------------------
Below is the explanation given by Redleaves (ID, the most hanging netizen):
Very detailed, very thorough, from the last conversation behind the original text, it can be seen that the standard understanding of C / C is very profound, worth learning :)
#pragma Pack (8)
Struct s1 {
Char a;
Long B;
}
Struct s2 {
Char C;
Struct S1 D;
Long long e;
}
#pragma pack ()
SizeOf (S2) results are 24.
Members have an important condition, that is, each member is aligned separately. Although each member is aligned in its own way.
That is to say, although the 8-byte alignment is specified, not all members are aligned with 8-byte. The rule of its alignment is, each member is aligned with the alignment parameters of its type (usually this type of size) And the specified alignment parameter (here is 8 bytes), and the length of the structure must be an integer multiple of all align parameters used, not enough to make up the fill byte. S1, member A is 1 byte The default is aligned in 1 byte, specifying the alignment parameter 8, these two values are 1, a Press 1 bytes; members B are 4 bytes, the default is to align by 4 bytes, then 4 words Sizeof (S1) should be 8;
In the S2, the C and S1 are aligned, but D is a structure, it is 8 bytes, what is it aligned? For the structure, its default alignment is all of its members The largest one in the alignment parameter, S1 is 4. So, member D is aligned in 4 bytes. Member E is 8 bytes, it is the default, according to the 8-byte alignment, the same as the specified, so it On the 8-byte boundary, at this time, 12 bytes have been used, so add 4 bytes of empty, starting from the 16th byte to place member E. At this time, the length is 24, already It can be divided by 8 (member E to 8 bytes). This uses a total of 24 bytes.
a b
S1 memory layout: 11 **, 1111,
C S1.A S1.B D
S2 memory layout: 1 ***, 11 **, 1111, **** 11111111
There are three points here:
1. Each member is aligned in its own way, and minimizes the length.
2. The default alignment of complex types (such as structures) is the alignment of its longest member, so that when members are complex types, the length can be minimized.
3. The length of the alignment must be an integer multiple of the largest alignment parameters in the member, which can guarantee each boundary alignment when processing an array.
For arrays, such as:
Char A [3]; this, its alignment and separate 3 char is the same. That is to say, it is aligned according to 1 byte.
If you write: typedef char Array3 [3];
Array3 This type of alignment is still aligned in one byte, not according to its length.
Regardless of the type, the aligned boundary must be one of 1, 2, 4, 8, 16, 32, 64 ....
Below is some additions from another article (http://community.9cbs.net/expert/topicview3.asp?id=3564500) to each type and structural alignment:
In order to enable the CPU to efficiently quickly access the variables, the starting address of the variable should have certain characteristics, that is, the so-called "alignment". For example, for 4-byte Int type variables, its starting address should be located on the 4-byte boundary, that is, the start address can be 4. The alignment rules of variables are as follows (32-bit system):
Type
Alignment
charr
Alignment on the byte boundary
SHORT (16-bit)
Alternate on the double-byte boundary
INT and long (32-bit)
Align in the 4-byte boundary
Float
Align in the 4-byte boundary
Double
Align in the 8-byte boundary
Structures
Consider a member of the structure alone, they are aligned on different byte boundaries.
The maximum number of byte boundaries is the number of byte boundaries of the structure.
This is a recursive process if there are structural members in the structure.
The maximum number of aligned byte boundaries set by the compiler is n, and for a member item in the structure, it is aligned with the actual byte of the structure of the structure.
Note x should meet the following rules:
X = min (n, sizeof (item))
For example, for structures
Struct {
Char a;
Long B;
} T;
When located in a 32-bit system, n = 8:
The offset of A is 0,
B The offset is 4, the middle is filled with 3 bytes, and the X is 4;
When located in a 32-bit system, n = 2:
The offset of A is 0,
B The offset is 2, and one byte is filled in the middle, and the X of B is 2;
SIZEOF:
The last member of the structure is LastItem, which is offset relative to the offset of the structure of the structure, which is a sizeOf (LastItem). The number of the structure of the structure is n, then: SIZEOF of the structure To: If Offset (LastItem) sizeOf (LastItem) can be divided by N, it is OFFSET (LastItem) sizeOf (LastItem), otherwise, it is filled in the back until it can be removed by N. In addition:
1) For the empty structure, sizeof == 1; because each instance of the structure must be ensured that there is a unique address in memory.
2) The static member of the structure does not affect the size of the structure, since the storage position of the static variable is independent of the instance address of the structure. E.g:
Struct {static int I;} t; structure {char A; static int i;} t1;
SIZEOF (T) == 1; SIZEOF (T1) == 1;
To make further understand the processing of the compiler on the structure and each variable alignment, especially the use of variables and structural size (SIZEOF usage)
Recommend the following article (unfortunately no one: ():
<< SizeOf, ultimate (on) >>: http://blog.9cbs.net/freefalcon/archive/2004/07/28/54839.aspx