Structure alignment in C Language

Source: Internet
Author: User

Structure alignment in C Language
Structure alignment in C Language

1, for example:

Struct {
Short A1;
Short A2;
Short A3;
};
Struct {
Long A1;
Short A2;
} B;
Sizeof (A) = 6, sizeof (B) = 8. Why?
Note: sizeof (short) = 2, sizeof (long) = 4

Because: "member alignment has an important condition that each member is aligned in its own way. The alignment rule is,Each member has a smaller alignment according to its type of alignment parameter (usually the size of this type) and the specified alignment parameter (8 bytes by default. in addition, the length of the structure must be an integer multiple of all alignment parameters used."(Reference)
Struct a has three short-type variables, each of which are aligned in 2 bytes. struct alignment parameters are aligned in 8 bytes by default. Then A1, A2, and A3 are both aligned in 2 bytes, then sizeof (a) is 6, which is also an integer multiple of 2;
In B, A1 is 4-byte alignment, A2 is 2-byte alignment, and the default alignment parameter of struct is 8. A1 is 4-byte alignment, A2 is 2-byte alignment, and struct size is 6 bytes, 6 is not an integer multiple of 4, and the byte is null. When it is increased to 8, if all conditions are met, the sizeof (B) is 8;

Can be set to alignment
# Pragma pack (1)
# Pragma pack (push)
# Pragma pack (1)
Struct {
Short A1;
Short A2;
Short A3;
};
Struct {
Long A1;
Short A2;
} B;
# The Pragma pack (POP) result is sizeof (A) = 6, sizeof (B) = 6

************************

2, for example:

# Pragma pack (8)
Struct S1 {
Char;
Long B;
};
Struct S2 {
Char C;
Struct S1 D;
Long long E;
};
# Pragma pack ()
The sizeof (S2) result is 24.
An important condition for member alignment is that each member is aligned separately. That is, each member is aligned in its own way.
That is to say, although alignment by 8 bytes is specified above, not all Members are alignment by 8 bytes. the alignment rule is that each member has a smaller alignment according to its type alignment parameter (usually the size of this type) and the specified alignment parameter (8 bytes here. in addition, the length of the structure must be an integer multiple of all alignment parameters used.
In S1, member A is 1 byte, which is aligned by 1 byte by default, and the specified alignment parameter is 8. Among the two values, 1 and a are aligned by 1 byte. Member B is 4 bytes, the default value is 4-byte alignment. In this case, it is 4-byte alignment, so sizeof (S1) should be 8;
In S2, C is the same as a in S1. It is aligned by 1 byte, while D is a structure. It is 8 bytes. What is its alignment? For the structure, its default alignment is the largest of all its members using alignment parameters, and S1 is 4. therefore, member D is aligned in 4 bytes. the member e is 8 bytes, which is aligned by 8 bytes by default. It is the same as the specified one, so it is connected to the boundary of 8 bytes. At this time, 12 bytes are used, therefore, four bytes are added, and the member e is placed starting from 16th bytes. at this time, the length is 24 and can be divisible by 8 (member e is aligned by 8 bytes. in this way, a total of 24 bytes are used.
A B
Memory layout of S1: 1 ***, 1111,
C s1.a s1. B E
Memory layout of S2: 1 *, 1 *, 1111, * 11111111

There are three important points:
1. Each Member is aligned in its own way, and the length can be minimized.
2. The default alignment of complex types (such as structures) is the alignment of its longest member, so that the length can be minimized when the member is a complex type.
3. The alignment length must be an integer multiple of the largest alignment parameter in the member. This ensures that each item is bounded when processing arrays.

In addition, for arrays, such:
Char A [3]; in this way, its alignment is the same as writing three char, that is, it is still aligned by 1 byte.
If you write: typedef char array3 [3];
The alignment of array3 type is still aligned by 1 byte, rather than by its length.
Whatever the type, the alignment boundary must be 1, 2, 4, 8, 16, 32, 64.
 
/***********************/
Byte alignment details
Why alignment?
In modern computers, memory space is divided by byte. Theoretically, it seems that access to any type of variables can start from any address, however, the actual situation is that access to specific types of variables is often performed at a specific memory address, which requires various types of data to be arranged in the space according to certain rules, instead of sequential emissions, this is alignment.
Alignment functions and causes: the processing of storage space varies greatly by hardware platform. Some platforms can only access certain types of data from some specific addresses. For example, some architectures may encounter errors when the CPU accesses a variable that is not aligned, so in this architecture, programming must ensure byte alignment. this may not be the case for other platforms, but the most common problem is that alignment of data storage according to the requirements of their platforms may cause a loss of access efficiency. For example, some platforms start from the even address each time they read data. If an int type (assuming a 32-bit System) is stored at the beginning of the even address, then a read cycle can read the 32bit data. If the data is stored at the beginning of the odd address, two read cycles are required, the 32-bit data can be obtained only when the high and low bytes of the two read results are pieced together. Obviously, reading efficiency is greatly reduced.

Ii. Effect of byte alignment on programs:
Let's take a few examples (32bit, x86 environment, GCC compiler ):
The struct is defined as follows:
Struct
{
Int;
Char B;
Short C;
};
Struct B
{
Char B;
Int;
Short C;
};
The length of various data types on 32-bit machines is known as follows:
CHAR: 1 (signed and unsigned)
Short: 2 (signed and unsigned)
INT: 4 (signed and unsigned)
Long: 4 (signed and unsigned)
Float: 4 double: 8
What is the size of the above two structures?
The result is:
The sizeof (strcut a) value is 8.
The value of sizeof (struct B) is 12.

Struct a contains a four-byte int, a one-byte char, and a two-byte short data. The same applies to B., B must be 7 bytes in size.
The above result is displayed because the compiler needs to align data members in space. The above is the result of alignment according to the default settings of the compiler. Can we change the default alignment settings of the compiler, of course? For example:
# Pragma pack (2)/* specify to align by 2 bytes */
Struct C
{
Char B;
Int;
Short C;
};
# Pragma pack ()/* cancel the specified alignment and restore the default alignment */
The value of sizeof (struct C) is 8.
Modify the alignment value to 1:
# Pragma pack (1)/* specify to align by 1 byte */
Struct d
{
Char B;
Int;
Short C;
};
# Pragma pack ()/* cancel the specified alignment and restore the default alignment */
The sizeof (struct d) value is 7.
Next we will explain the role of # pragma pack.

Iii. What principles does the compiler align?
Let's take a look at four important basic concepts:
1. Alignment of data types:
For char data, its own alignment value is 1, for short data is 2, for int, float, double type, its own alignment value is 4, in bytes.
2. The alignment value of a struct or class: The value with the largest alignment value among its members.
3. Specify the alignment value: # The alignment value specified when Pragma pack (value) is used.
4. Valid alignment values of data members, struct, and classes: the alignment value of the data itself and the value smaller than the specified alignment value.
With these values, we can easily discuss the data structure members and their alignment. The valid alignment value n is the final value used to determine the data storage address. Valid alignment means "alignment on N", that is, the "Starting address for storing the data % n = 0 ". data variables in the data structure are discharged in the defined order. The starting address of the first data variable is the starting address of the data structure. The member variables of the struct must be aligned and discharged, and the struct itself must be rounded according to its own valid alignment values (that is, the total length occupied by the member variables of the struct must be an integer multiple of the valid alignment values of the struct, ). In this way, you cannot understand the values of the above examples.
Example Analysis:
Analysis example B;
Struct B
{
Char B;
Int;
Short C;
};
False B is discharged from the address space 0x0000. The alignment value is not defined in this example. In the author's environment, this value is 4 by default. The first member variable B's own alignment value is 1, which is smaller than the specified or default alignment value 4. Therefore, the valid alignment value is 1, therefore, the storage address 0x0000 is 0 x 0000% 1 = 0. the alignment value of the second member variable A is 4, so the valid alignment value is 4. Therefore, it can only be stored in the four consecutive bytes from the starting address 0x0004 to 0x0007, review 0 x 0004% 4 = 0, which is close to the first variable. The third variable C has its own alignment value of 2, so the valid alignment value is also 2, which can be stored in the two bytes from 0x0008 to 0x0009, Which is 0 x 0008% 2 = 0. Therefore, B content is stored from 0x0000 to 0x0009. Then, let's look at the alignment value of Data Structure B as the maximum alignment value in its variable (here it is B), so it is 4, so the valid alignment value of the structure is also 4. According to the requirements of the structure, 0x0009 to 0x0000 = 10 bytes, (10 + 2) % 4 = 0. Therefore, 0x0000a to 0x000b is also occupied by struct B. Therefore, B has a total of 12 bytes from 0x0000 to 0x000b, and sizeof (struct B) = 12. In fact, if this one is used, it will satisfy the byte alignment, because its starting address is 0, it must be aligned. The reason why two bytes are added to the end is that the compiler aims to achieve the access efficiency of the structure array, imagine if we define an array of structure B, then the starting address of the first structure is 0, but what about the second structure? According to the definition of the array, all elements in the array are adjacent. If we do not add the size of the structure to an integer multiple of 4, the starting address of the next structure will be 0x0000a, this obviously cannot satisfy the address alignment of the structure, so we need to add the structure to an integer multiple of the valid alignment size. in fact, for char type data, its own alignment value is 1, for short type is 2, for int, float, double type, its own alignment value is 4, the alignment values of these existing types are also based on arrays. They are known only because their lengths are known.
Similarly, analyze the above example C:
# Pragma pack (2)/* specify to align by 2 bytes */
Struct C
{
Char B;
Int;
Short C;
};
# Pragma pack ()/* cancel the specified alignment and restore the default alignment */
The first variable B's own alignment value is 1 and the specified alignment value is 2. Therefore, the valid alignment value of B is 1. Suppose C starts from 0x0000, then B is stored in 0x0000, conforms to 0 x 0000% 1 = 0; the second variable, its own alignment value is 4, and the specified alignment value is 2, so the valid alignment value is 2, therefore, the sequence is stored in four consecutive bytes, namely 0x0002, 0x0003, 0x0004, and 0 x 0002%. The alignment value of the third variable C is 2, so the valid alignment value is 2, which is stored in sequence.
In 0x0006, 0x0007, 0 x 0006% 2 = 0. Therefore, from 0x0000 to 0x00007, a total of eight characters are stored in the C variable. And C's own alignment value is 4, so the valid alignment value of C is 2. Again 8% 2 = 0, C only occupies eight bytes from 0x0000 to 0x0007. So sizeof (struct c) = 8.

4. How to modify the default alignment value of the compiler?
1. in vc ide, you can modify it as follows: [project] | [settings], in struct member alignment of code generation option of C/C ++ tab category. The default value is 8 bytes.
2. You can modify the code dynamically as follows: # pragma pack. Note: It is Pragma instead of progma.

5. How should we consider byte alignment in programming?

If we want to save space during programming, we only need to assume that the first address of the structure is 0, and then sort the variables according to the above principles, the basic principle is to declare the variables in the structure according to the type size from small to large, and minimize the space to fill. another method is to align the filled space in order to exchange space for time efficiency. For example, one method of using space for time is to explicitly insert reserved members:
Struct {
Char;
Char reserved [3]; // use space for time
Int B;
}

The reserved member has no significance for our program. It just fills the space to achieve byte alignment. Of course, even if this member is not added, the compiler will automatically fill the alignment for us, we add it as an explicit reminder.

6. potential risks of byte alignment:
Many of the potential alignment risks in the Code are implicit. For example, in forced type conversion. For example:
Unsigned int I = 0x12345678;
Unsigned char * P = NULL;
Unsigned short * P1 = NULL;

P = & I;
* P = 0x00;
P1 = (unsigned short *) (p + 1 );
* P1 = 0x0000;
The last two sentences of code access the unsignedshort variable from the odd boundary, which obviously does not comply with the alignment rules.
On x86, similar operations only affect the efficiency, but on MIPS or iSCSI, they may be an error because they must be in byte alignment.

7. How to find problems with byte alignment:
If alignment or assignment occurs, first check
1. Compiler's big little side settings
2. Check whether the system supports non-alignment access.
3. If alignment or alignment is supported, some special modifications are required to mark special access operations.

Alignment processing under arm
From dui0067d_ads1_2_complib

3.13 type qulifiers

Some of them are taken from the alignment section of the arm compiler documentation.

Alignment usage:
1. _ align (Num)
This is used to modify the byte boundary of the highest level object. When ldrd or strd is used in assembly
This command _ align (8) is required for modification. To ensure that the data objects are aligned accordingly.
The command for modifying an object can contain a maximum of 8 bytes, so that a 2-Byte object can be 4 bytes long.
Alignment, but cannot make the 4-Byte object 2-byte alignment.
_ Align is a storage class modification. It only modifies objects of the highest level and cannot be used for structures or function objects.

2. _ packed
_ Packed is used for one-byte alignment.
1. The packed object cannot be aligned.
2. Read and Write Access to all objects is non-aligned.
3. Float and the objects containing the float Structure union and unused _ packed cannot be aligned in bytes.
4. _ packed has no effect on partial Integer Variables
5. Forced conversion from unpacked object to packed object is undefined, and integer pointer can be set legally
The value is packed.
_ Packed int * P; // _ packed int indicates no meaning.
6. Problems with alignment or non-alignment read/write access
_ Packed struct struct_test
{
Char;
Int B;
Char C;
}; // Define the following structure. At this time, the starting address of B must be not aligned.
// Access B in the stack may be faulty, because the data on the stack must be alignally accessed [from Cl]
// Define the following variables as Global static not on the stack
Static char * P;
Static struct struct_test;
Void main ()
{
_ Packed int * q; // It is defined as _ packed to modify the access under the Non-Alignment data address of the current Q.

P = (char *) &;
Q = (int *) (p + 1 );
 
* Q = 0x87654321;
/*
The Assembly command that gets the value assignment is clear.
LDR R5, 0x20001590; = #0x12345678
[0xe1a00005] mov r0, R5
[0xeb1_b0] BL _ rt_uwrite4 // call an operation function to write 4 bytes here

[0xe5c10000] strb r0, [R1, #0] // The function performs four strb operations and then returns the result to ensure correct data access.
[0xe1a02420] mov R2, R0, LSR #8
[0xe5c12001] strb R2, [R1, #1]
[0xe1a02820] mov R2, R0, LSR #16
[0xe5c12002] strb R2, [R1, #2]
[0xe1a02c20] mov R2, R0, LSR #24
[0xe5c12003] strb R2, [R1, #3]
[0xe1a0f00e] mov PC, R14
*/

/*
If Q is not decorated with _ packed, the compiled command will directly cause access to the odd address to fail.
[0xe59f2018] LDR R2, 0x20001594; = #0x87654321
[0xe5812000] STR R2, [R1, #0]
*/

// This clearly shows how non-alignment access produces errors.
// And how to eliminate problems caused by non-alignment access
// You can also see that the command difference between non-alignment access and alignment access causes efficiency problems.
}

Sizeof determines the struct size

Typedef struct
{
Int;
Char B;
} A_T;
Typedef struct
{
Int;
Char B;
Char C;
} B _t;
Typedef struct
{
Char;
Int B;
Char C;
} C_t;
Void main ()
{
Char * A = 0;
Cout <sizeof (a) <Endl; // 4
Cout <sizeof (* A) <Endl; // 1 -- this is understandable.
Cout <sizeof (a_T) <Endl; // 8
Cout <sizeof (B _t) <Endl; // 8
Cout <sizeof (c_t) <Endl; // 12
}
Why is that?

2. Syntax:
Sizeof has three syntax forms:
1) sizeof (object); // sizeof (object );
2) sizeof (type_name); // sizeof (type );
3) sizeof object; // sizeof object;

 

5. sizeof pointer variable
Since the address is stored, it is equal to the width of the computer's internal address bus. So in a 32-bit computer

The return value of each pointer variable must be 4 (in bytes). It can be predicted that in the future 64-bit System

The sizeof result of the pointer variable in is 8.
Char * Pc = "ABC ";
Int * PI;
String * pS;
Char ** PPC = & PC;
Void (* PF) (); // function pointer
Sizeof (PC); // The result is 4
Sizeof (PI); // The result is 4
Sizeof (PS); // The result is 4
Sizeof (PPC); // The result is 4
Sizeof (PF); // The result is 4
The sizeof value of the pointer variable has no relationship with the object indicated by the pointer. It is precisely because all pointer variables occupy the memory.

The size is equal, so the MFC message processing function uses two parameters wparam and lparam to transmit various complex message knot

Structure (use a pointer to the struct ).

6. sizeof of Array
The sizeof value of the array is equal to the number of memory bytes occupied by the array, for example:
Char A1 [] = "ABC ";
Int A2 [3];
Sizeof (A1); // The result is 4. A null Terminator exists at the end of the string.
Sizeof (A2); // The result is 3*4 = 12 (dependent on INT)
Some friends regard sizeof as the number of elements in the array at the beginning. Now, you should know that this is wrong.

How should we calculate the number of array elements? Easy, there are two methods:
Int C1 = sizeof (A1)/sizeof (char); // total length/length of a single element
Int C2 = sizeof (A1)/sizeof (A1 [0]); // total length/length of the first element
Write it here and ask, what is the value of C3 and C4 below?
Void foo3 (char A3 [3])
{
Int C3 = sizeof (A3); // C3 =
}
Void foo4 (char A4 [])
{
Int C4 = sizeof (A4); // C4 =
}
Maybe when you try to answer the C4 value, you realize that C3 is wrong. Yes, C3! = 3. The function parameter A3 is no longer

The array type is converted to a pointer, which is equivalent to char * A3. Why? If you think about it, it's hard to understand that we call

When the function foo1 is used, will the program allocate an array of 3 on the stack? No! The array is "transferred", the caller

You only need to pass the real parameter address, so A3 is a pointer type (char *), and the C3 value is 4.

7. sizeof of struct
This is the most frequently asked question for beginners, so it is necessary to pay more attention here. Let's first look at a struct:

Struct S1
{
Char C;
Int I;
};
What is sizeof (S1) equal? Smart, you start to think about it. Char occupies 1 byte and INT occupies 4 byte.

It should be 5. Is that true? Have you tried it on your machine? Maybe you are right, but you are probably wrong! V

In C6, the default value is 8.
Why? Why is my injury always me?
Don't be frustrated. Let's take a look at the definition of sizeof. The result of sizeof is equal to the value of an object or type.

The number of memory bytes. Well, let's look at the memory allocation of S1:
S1 S1 = {A, 0 xffffffff };
After defining the above variables, add breakpoints, run the program, and observe the memory where S1 is located. What did you find?
Take my vc6.0 as an example. The S1 address is 0x0012ff78, and its data content is as follows:
0012ff78: 61 CC FF
What have you found? Why is CC mixed with 3 bytes in the middle? Let's take a look at the description on msdn:
When applied to a structure type or variable, sizeof returns the actual size,

Which may include Padding Bytes inserted for alignment.
Originally, this is the legendary byte alignment! An important topic has emerged.
Why do we need byte alignment? The principle of computer composition teaches us how to speed up computer data acquisition. Otherwise

It takes more time to execute the command cycle. For this reason, the compiler will process the struct by default (in fact, the data changes elsewhere)

So that the basic data type (short, etc.) whose width is 2 is located on the address that can be divisible by 2, so that the width is

The basic data type (such as INT) of 4 is located on the address that can be divisible by 4, and so on. In this way, the two numbers are in the middle.

You may need to add the padding byte, so the sizeof value of the entire struct increases.
Let's exchange the positions of char and INT in S1:
Struct S2
{
Int I;
Char C;
};
Let's see what the result of sizeof (S2) is. Why is it 8? Let's look at the memory. The original member C still has three fill characters behind it.

Why? Don't worry. Let's summarize the rules below.

The details of byte alignment are related to compiler implementation, but generally three criteria are met:
1) The first address of the struct variable can be divisible by the size of its widest basic type member;
2) The offset (offset) of each member of the struct to the first address of the struct is an integer multiple of the member size.

The compiler needs to add the padding byte (internal adding) between the members );
3) the total size of the struct is an integer multiple of the size of the widest basic type of the struct. If necessary, the compiler will

Add the padding byte (trailing padding) after the members ).
There are several notes for the above principles:
1) I didn't say that the address of a struct member is an integer multiple of its size. How can I talk about the offset? Because of

One point exists, so we can only consider the member offset, which is easy to think about. Think about why.
The offset of a member of the struct to the first address of the struct can be obtained through the macro offsetof ().

Defined in stddef. h as follows:
# Define offsetof (S, m) (size_t) & (S *) 0)-> m)
For example, to get the offset of C in S2, the method is
Size_t Pos = offsetof (S2, c); // POS equals 4
2) The basic type refers to the built-in data types mentioned above, such as char, short, Int, float, and double,

The "data width" here refers to the size of its sizeof. Because the structure member can be of the composite type

For another struct, when looking for the widest basic type member, it should include the child members of the composite type member,

Instead of seeing a composite member as a whole. However, when determining the offset of a composite member

As a whole.
This is a bit difficult to describe here, and it seems a bit confusing to think about it. Let's take a look at the example (the specific value is still based on VC

6 ):
Struct S3
{
Char C1;
S1 S;
Char C2
};
The type of the widest and simplest member in S1 is int. When S3 considers the widest and simplest type member, it "disconnects" S1, so

S3 has the widest and simplest type of Int. In this way, the first address of the bucket needs to be divisible by four and rounded by the variables defined by S3.

Sizeof (S3) values should also be divided by 4.
The offset of C1 is 0. What is the offset of S? At this time, S is a whole. As a struct variable, S satisfies the first three principles.

So the size is 8 and the offset is 4. Three bytes are needed between C1 and S, and no space is needed between C2 and S,

So the offset of C2 is 12, and the size of C2 is 13, and 13 cannot be divisible by 4. In this way, three values must be filled at the end.

Byte. Finally, the value of sizeof (S3) is 16.
Through the above description, we can get a formula:
The size of the struct is equal to the offset of the last member plus the size of the struct plus the number of filled bytes at the end, that is:

Sizeof (struct) = offsetof (last item) + sizeof (TRAIL

Ing padding)

Here, friends should have a brand new understanding of the sizeof struct, but don't be too happy.

An important parameter that affects sizeof is the pack instruction of the compiler. It is used to adjust the structure alignment.

Different compiler names and usages are slightly different. In vc6, the # pragma pack is used for implementation and can be directly modified.

/ZP compilation switch. # The basic usage of The Pragma pack is: # pragma pack (N). N indicates the number of bytes alignment. The value is

The values are 1, 2, 4, 8, and 16. The default value is 8. If the value is smaller than the sizeof value of the struct, the offset of the member

The amount should take this value as the standard, that is, the offset of the struct member should take the minimum value of the two. The formula is as follows:
Offsetof (item) = min (n, sizeof (item ))
Let's look at the example:
# Pragma pack (push) // Save the current pack setting pressure Stack
# Pragma pack (2) // must be used before struct Definition
Struct S1
{
Char C;
Int I;
};
Struct S3
{
Char C1;
S1 S;
Char C2
};
# Pragma pack (POP) // restore previous pack settings
When sizeof (S1) is calculated, the value of min (2, sizeof (I) is 2, so the offset of I is 2, and the value of sizeof (I) is equal

6, can be divisible by 2, so the size of the entire S1 is 6.
Similarly, for sizeof (S3), the offset of S is 2, the offset of C2 is 8, and the addition of sizeof (C2) is equal to 9, cannot be

2 Division, add a fill byte, so sizeof (S3) is equal to 10.
Now, friends can breathe a sigh of relief,

Note that the size of the "Empty struct" (excluding data members) is not 0, but 1. Imagine a "not occupied"

How can space variables be distinguished by their addresses and two different "Empty struct" variables? Therefore,"

The empty struct variable has to be stored, so that the compiler can allocate only one byte of space for occupying space.

As follows:
Struct S5 {};
Sizeof (S5); // The result is 1.

8. sizeof containing bitfield struct
As mentioned above, bitfield members cannot be taken sizeof values independently. Here we will discuss struct containing bitfield.

The sizeof of is specifically listed in consideration of its particularity.
C99 specifies that int, unsigned int, and bool can be used as bit domain types, but almost all compilers have extended this, allowing

Other types may exist.
The main purpose of bit domains is to compress storage. The general rules are as follows:
1) if the type of the adjacent bit field is the same and the sum of its bit width is smaller than the sizeof size of the type

Store the preceding field until it cannot be accommodated;
2) If the types of adjacent bit fields are the same, but the sum of Bit Width is greater than the sizeof size of the type

The offset of a new storage unit is an integer multiple of its type;
3) if the types of adjacent bitfield fields are different, the implementations of each compiler are different. vc6 adopts the non-compression mode.

, Dev-C ++ adopts the compression method;
4) do not compress fields that are interspersed with non-bit fields;
5) the total size of the entire struct is an integer multiple of the size of the widest basic type.

Let's take a look at the example.
Example 1:
Struct bf1
{
Char F1: 3;
Char F2: 4;
Char F3: 5;
};
Its memory layout is:
| _ F1 __|__ F2 __| _ | ____ F3 ___ | ____ |
| _ |
0 3 7 8 1316
The bit field type is Char, and the 1st bytes can only accommodate F1 and F2, so F2 is compressed to 1st bytes, while F3 can only

Starting from the next byte. Therefore, the result of sizeof (bf1) is 2.
Example 2:
Struct bf2
{
Char F1: 3;
Short F2: 4;
Char F3: 5;
};
Because the adjacent bit fields have different types, in vc6, sizeof is 6, and in Dev-C ++ is 2.
Example 3:
Struct bf3
{
Char F1: 3;
Char F2;
Char F3: 5;
};
The non-bit field is interspersed in it and will not produce compression. The size obtained in vc6 and Dev-C ++ is 3.

9. sizeof of the Consortium
The struct structure is sequential in the memory structure, while the consortium is overlapping. Each member shares a memory segment, so the entire connection

The sizeof of each member is the maximum value of sizeof. Struct members can also be composite. Here,

Composite Members are considered as a whole.
Therefore, in the following example, the sizeof value of U is equal to sizeof (s ).
Union u
{
Int I;
Char C;
S1 S;
};

This article from the csdn blog, reproduced please indicate the source: http://blog.csdn.net/malpin/archive/2008/03/08/2157895.aspx

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.