If the struct member is directly manipulated, it will not take the unexpected value
However, alignment issues need to be considered for continuous data formats
such as data frame formats in communications, such as IP packets, etc.
#pragma pack (1)
struct TAGSTRUCT
{
...
}
T
#pragma pack ()
The way to force continuous storage
Where the front pack (1) means the alignment boundary is 1
1 . Examples of several structural bodies:
struct{
Short A1;
Short A2;
Short A3;
}a;
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 in which each member is aligned in its own way." The rule of alignment is that each member is aligned to the lesser of its type's alignment parameters (usually the size of this type) and the specified alignment parameters (here by default, 8 bytes). And the length of the structure must be an integer multiple of all the alignment parameters used, not enough to fill the empty bytes. "(citation)
struct A has 3 short types of variables, each with 2-byte alignment, the structure alignment parameters are aligned by the default 8 bytes, then a1,a2,a3 2-byte alignment, then sizeof (A) is 6, which is also an integer multiple of 2;
B in the A1 is 4-byte alignment, A2 is 2-byte alignment, the struct default alignment parameter is 8, then A1 4-byte alignment, A2 take 2-byte alignment, struct size 6 bytes, 6 not 4 integer times, fill the empty byte, increase to 8 o'clock, meet all conditions, sizeof (B) is 8;
Can be set to an aligned
#pragma pack (1)
#pragma pack (push)
#pragma pack (1)
struct{
Short A1;
Short A2;
Short A3;
}a;
struct{
Long A1;
Short A2;
}b;
#pragma pack (POP)
The result is sizeof (A) =6,sizeof (B) =6
************************
#pragma pack (8)
struct s1{
Char A;
Long B;
};
struct S2 {
char c;
struct S1 D;
Long long E;
};
#pragma pack ()
sizeof (S2) result is 24.
Member alignment has an important condition in which each member is aligned, that is, each member is aligned in its own way.
This means that although the above specifies a 8-byte alignment, not all members are aligned in 8-byte terms. The rule of alignment is that each member is aligned to the lesser of its type's alignment parameters (usually the size of this type) and the specified alignment parameters (here is 8 bytes). And the length of the structure must be an integer multiple of all the alignment parameters used, not enough to fill the empty bytes.
In S1, member A is 1 bytes by default by 1-byte alignment, the alignment parameter is 8, the two values are 1,a by 1 bytes, the member B is 4 bytes, by default is 4 byte aligned, then by 4 byte alignment, so sizeof (S1) should be 8;
S2, C and a in S1, as in 1-byte alignment, and D is a structure, it is 8 bytes, what is it aligned? For structs, its default alignment is the largest of the alignment parameters used by all its members, and S1 is 4. So, member D is aligned by 4 bytes. The member E is 8 bytes, it is the default by 8 byte alignment, and the same as specified, so it is on the boundary to 8 bytes, at this point, has used 12 bytes, so added 4 bytes of empty, starting from the 16th byte to place the member E. At this point, the length is 24, which can already be divisible by 8 (Member E by 8-byte alignment). In this way, 24 bytes are used altogether.
A b
S1 Memory layout: 1***, 1111,
C s1.a s1.b E
S2 Memory layout: 1***, 1***, 1111, ****11111111
Here are three important points:
1. Each member is aligned in its own way and can minimize the length
2. The default alignment of a complex type, such as a structure, is the alignment of its longest member, so that the length can be minimized when the member is a complex type
3. The length of the alignment must be an integer multiple of the largest alignment parameter in the member, so that each item is bound to the boundary when the array is processed
To add, for arrays, such as:
Char a[3]; this is the same way that it is aligned and writes 3 char respectively. This means that it is still aligned in 1 bytes.
If write: typedef char ARRAY3[3];
Array3 This type of alignment is still aligned by 1 bytes, not by its length.
Regardless of the type, the aligned boundary must be one of the 1,2,4,8,16,32,64 ....
/***********************/
BYTE justification
Why are you aligning?
The memory space in modern computers is divided by Byte, in theory it seems that access to any type of variable can start from any address, but the reality is that when accessing a particular type of variable, it is often accessed at a specific memory address, which requires all types of data to be spatially arranged according to certain rules, Instead of sequentially one by one emissions, that's the alignment.
The effect and reason of alignment: the processing of storage space varies greatly with each hardware platform. Some platforms can only access certain types of data from certain specific addresses. For example, some architectures have an error when accessing a variable that is not aligned, so programming must ensure byte alignment in this architecture. Other platforms may not have this, but the most common is the loss of access efficiency if the data storage is not aligned as appropriate for its platform requirements. For example, some platforms read each time from the even address, if an int (assuming 32-bit system) if the location of the place where the even address begins, then a read cycle can be read out of the 32bit, and if it is stored at the beginning of the odd address, it takes 2 read cycles, The 32bit data can be obtained by piecing together the high and low bytes of the two read-out results. Obviously, the reading efficiency is much lower.
Two. The effect of byte alignment on the program:
Let's take a look at some examples (32bit,x86 environment, GCC compiler):
The structure is defined as follows:
struct A
{
int A;
Char b;
Short C;
};
struct B
{
Char b;
int A;
Short C;
};
The lengths of the various data types on the 32-bit machine are now known as:
Char:1 (Signed and unsigned)
Short:2 (Signed and unsigned)
Int:4 (Signed and unsigned)
Long:4 (Signed and unsigned)
Float:4 Double:8
So what's the size of the top two structures?
The result is:
sizeof (Strcut A) value is 8
sizeof (struct B) has a value of 12.
struct A contains 4-byte-length int one, 1-byte-length char one and 2-byte length of short data one, B is the same;
The result above is because the compiler wants to align the data members spatially. The above is the result of the alignment according to the compiler's default settings, then we can not change the compiler's default alignment settings, of course. For example:
#pragma pack (2)/* Specify 2-byte alignment */
struct C
{
Char b;
int A;
Short C;
};
#pragma pack ()/* To cancel the specified alignment, restore the default alignment */
The sizeof (struct C) value is 8.
Modify the alignment value to 1:
#pragma pack (1)/* Specify 1-byte alignment */
struct D
{
Char b;
int A;
Short C;
};
#pragma pack ()/* To cancel the specified alignment, restore the default alignment */
The sizeof (struct D) value is 7.
Later we explain the role of #pragma pack ().
Three. What are the principles that the compiler aligns?
Let's start by looking at four important basic concepts:
1. The alignment value of the data type itself: for char type data, its own alignment value is 1, for the short type is 2, for the int,float,double type, its own alignment value is 4, the unit byte.
2. The self-aligning value of a struct or class: The value that is the largest of its members in its own alignment value.
3. Specify the alignment value: The specified alignment value when #pragma pack (value) is values.
4. Valid alignment values for data members, structs, and classes: The value that is small for its own alignment value and for the specified alignment value.
With these values, we can easily discuss the members of a specific data structure and its own alignment. The valid alignment value n is the value that is ultimately used to determine how the data is stored, most importantly. A valid alignment of n means "align on n", meaning that the data "holds the starting address%n=0". Data variables are emitted in a defined order of precedence. The starting address of the first data variable is the starting address of the structure. The member variables of the struct should be aligned with the emission, and the structure itself should be rounded according to its own valid alignment value (that is, the total length of the struct member variable is required to be an integral multiple of the effective alignment value of the struct, as the following example understands). This makes it impossible to understand the values of several examples above.
Example Analysis:
Analysis Example B:
struct B
{
Char b;
int A;
Short C;
};
Suppose B starts discharging from the address space 0x0000. In this example, the specified alignment value is not defined, and in the author's environment, the value defaults to 4. The first member variable B has a self-aligning value of 1, which is smaller than the specified or default alignment value of 4, so its valid alignment value is 1, so its storage address 0x0000 conforms to 0x0000%1=0. The second member variable, a, has its own alignment value of 4, so the valid alignment value is also 4, so it can only be stored in four contiguous byte spaces with a starting address of 0x0004 to 0x0007, which conforms to 0x0004%4=0 and is immediately adjacent 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 byte space of 0x0008 to 0x0009, conforming to 0x0008%2=0. So everything from 0x0000 to 0x0009 is stored in B content. Then look at the data structure B's own alignment value for its variable maximum alignment value (here is B) so is 4, so the structure of the effective alignment value is also 4. 0x0009 to 0x0000=10 bytes, (10+2)%4=0 according to the requirements of the structural rounding. So 0x0000a to 0x000b is also occupied by struct B. So B has a total of 12 bytes from 0x0000 to 0x000b, sizeof (struct B) = 12; In fact, if that's the case, it's already aligned with the byte, because its starting address is 0, so it's definitely aligned. 2 bytes are added later because the compiler is trying to achieve the access efficiency of the structure array, imagine if we define an array of struct B, then the first struct start address is 0 no problem, but the second one? As defined by the array, all elements in the array are next to each other, and if we do not add the size of the structure to an integer multiple of 4, then the starting address of the next structure will be 0x0000a, which obviously does not satisfy the structure's address alignment, so we want to add the structure to an integer multiple of the effective alignment size. In fact, such as: for char data, its own alignment value of 1, for the short type of 2, for the int,float,double type, its own alignment value of 4, these existing types of self-aligning values are also based on the array, just because these types of length is known, So their own alignment values are already well-established.
Similarly, analyze the above example C:
#pragma pack (2)/* Specify 2-byte alignment */
struct C
{
Char b;
int A;
Short C;
};
#pragma pack ()/* To cancel the specified alignment, restore the default alignment */
The first variable B has its own alignment value of 1, the specified alignment value is 2, so its valid alignment value is 1, assuming that C starts with 0x0000, then B is stored in 0x0000, conforms to 0x0000%1= 0, the second variable has its own alignment value of 4, and the alignment value is 2, so the valid alignment value is 2. So the order is stored in 0x0002, 0x0003, 0x0004, 0x0005 four consecutive bytes, in accordance with 0x0002%2=0. The third variable C has its own alignment value of 2, so the valid alignment value is 2, which is stored in 0x0006, 0x0007, and conforms to 0x0006%2=0. So from 0x0000 to 0x00007 a total of eight bytes is stored in the C variable. and C has its own alignment value of 4, so the valid alignment value for C is 2. And 8%2=0,c only takes up eight bytes of 0x0000 to 0x0007. So sizeof (struct C) = 8.
Four. How do I modify the compiler's default alignment values?
1. In the VC IDE, you can modify this: [project]| [settings],c/c++ tab category of the Code generation option of the struct Member alignment modified, the default is 8 bytes.
2. When encoding, you can modify this dynamically: #pragma pack (value). Note: It is pragma and not progma.
Five. For byte alignment, what do we consider in programming?
If you want to consider saving space when programming, then we only need to assume that the first address of the structure is 0, then the various variables are arranged according to the above principles, the basic principle is to make the variables in the structure according to the type size, from small to large declaration, as far as possible to reduce the middle of the filling space. There is another way to make space for the efficiency of time, we show the space to fill the alignment, for example: there is a use of space-time approach is to explicitly insert reserved members:
struct a{
Char A;
Char reserved[3];//use space to change time
int b;
}
The reserved member has no meaning to our program, it just fills the space to achieve byte alignment, and of course even without this member the compiler will automatically fill us with the alignment, and we add it just to play an explicit reminder.
Six. Possible pitfalls of byte alignment:
Many of the pitfalls of alignment in code are implicit. For example, when forcing type conversions. 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 lines of code, from the odd boundary to access the Unsignedshort variable, clearly do not conform to the rules of alignment.
On x86, similar operations can only affect efficiency, but on MIPS or SPARC, it can be an error because they require byte alignment.
Seven. How to find problems with byte alignment:
If an alignment or assignment problem occurs, first view
1. Compiler's big little side settings
2. See if the system itself supports non-aligned access
3. If the support depends on whether the alignment is set or not, if there is no access, you need to add some special decorations to flag its special access operation.
Alignment processing under Arm
From Dui0067d_ads1_2_complib
3.13 Type Qulifiers
Partial excerpt from ARM compiler document alignment Section
Use of alignment:
1.__align (num)
This is used to modify the byte bounds of the highest-level object. This command is used when using LDRD or STRD in the Assembly __align (8) for cosmetic restrictions. To ensure that the data Objects are aligned accordingly. The maximum command for this decorated object is a 8-byte limit, which allows 2-byte objects to be 4-byte aligned, but not 4 bytes of object 2-byte alignment. __align is a storage class modification, and he only modifies the top type objects that cannot be used for structs or function objects.
2.__packed
__packed is a byte-aligned 1. Cannot align packed objects 2. Read-write access for all objects is non-aligned access
3.float and the structure containing float and unused __packed objects will not be byte-aligned
4.__packed has no effect on local shaping variables
5. Forcing conversions from unpacked objects to packed objects is undefined, and shaping pointers can be legally defined as packed. __packed int* p;//__packed int is meaningless
6. Alignment or non-aligned read-write access poses a problem
__packed struct Struct_test
{
Char A;
int b;
char c;
} ; Define the following structure at this point, the start address of B must be misaligned.
There may be a problem accessing B in the stack because the data on the stack is definitely aligned access [from CL]
Define the following variables as global static not on the stack
Static char* p;
static struct struct_test A;
void Main ()
{
__packed int* Q; This is defined as __packed to decorate the access below the current Q point to a non-aligned data address, which can be
p = (char*) &a;
Q = (int*) (p+1);
*q = 0x87654321;
/*
The assembly instructions that get the assignment are clear.
LDR r5,0x20001590; = #0x12345678
[0xe1a00005] mov r0,r5
[0xeb0000b0] BL __rt_uwrite4//Call a write 4byte operation function here
[0xe5c10000] Strb r0,[r1, #0]//function to perform 4 STRB operations and then return to ensure the correct access to the data
[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 does not have a __packed modifier then the assembler command is such that direct access to the singular address fails
[0xe59f2018] Ldr r2,0x20001594; = #0x87654321
[0xe5812000] str r2,[r1, #0]
*/
This makes it clear how non-aligned access produces errors.
And how to eliminate non-aligned access poses problems
You can also see non-aligned Access and aligned access instruction differences leading to efficiency issues
}
The determination of the size of the structure by sizeof
typedef struct
{
int A;
Char b;
}a_t;
typedef struct
{
int A;
Char b;
char c;
}b_t;
typedef struct
{
Char A;
int b;
char c;
}c_t;
void Main ()
{
char*a=0;
Cout<<sizeof (a) <<ENDL;//4
Cout<<sizeof (*a) <<endl;//1--This can understand
Cout<<sizeof (a_t) <<ENDL;//8
Cout<<sizeof (b_t) <<ENDL;//8
Cout<<sizeof (c_t) <<ENDL;//12
}
Why is this the result?
2. Syntax:
sizeof has three grammatical forms, as follows:
1) sizeof (object); sizeof (object);
2) sizeof (TYPE_NAME); sizeof (type);
3) sizeof object; sizeof object;
5. sizeof for pointer variables
Since it is to store the address, it certainly equals the width of the internal address bus of the computer. So in a 32-bit computer, the return value of a pointer variable must be 4 (in bytes), and you can expect that the sizeof result of the pointer variable in a future 64-bit system is 8.
char* PC = "ABC";
int* Pi;
string* PS;
char** PPC = &pc;
void (*PF) ();//function pointer
sizeof (PC); Result is 4
sizeof (PI); Result is 4
sizeof (PS); Result is 4
sizeof (PPC); Result is 4
sizeof (PF);//result is 4
The sizeof value of the pointer variable does not have anything to do with the object that the pointer refers to, because all pointer variables are equal in memory size, so the MFC message processing function uses two parameters wparam, lparam to pass a variety of complex message structures (using pointers to the struct body).
6. The sizeof array
The sizeof value of the array equals the number of bytes of memory occupied by the array
Such as:
Char a1[] = "ABC";
int a2[3];
sizeof (A1); The result is 4, and there is a null terminator at the end of the string
sizeof (A2); Result is 3*4=12 (dependent on int)
Some friends start with sizeof as the number of array elements, now, you should know that this is not right, then how to find the number of array elements? Easy, usually has the following two kinds of wording:
int c1 = sizeof (A1)/sizeof (char); Total length/length of individual elements
int c2 = sizeof (A1)/sizeof (a1[0]); Total length/length of first element
Write here, ask, the following C3,C4 value should be how much?
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 C4 's value, you realize that C3 answered wrong, yes, c3!=3. Here the function parameter A3 is no longer an array type, but is transformed into a pointer, equivalent to char* A3, why? It's not hard to think about it. When we call the function foo1, will the program allocate an array of size 3 on the stack? No! An array is a "pass-through", where the caller simply passes the address of the argument, so A3 is naturally the pointer type (char*), and the value of C3 is 4.
7. sizeof of the structure
This is a question that beginners ask most, so it is necessary to pay more and more ink. Let's look at a structure first:
struct S1
{
char c;
int i;
};
Q. How much does sizeof (S1) equal? Smart you start to think, char accounted for 1 bytes, int accounted for 4 bytes, then add up should be 5. Is that right? Have you tried it on your machine? Maybe you're right, but you're probably wrong! The result of the default setting in VC6 is 8.
Why? Why is it always me that hurts? Please don't be depressed, let's take a good look at the definition of sizeof the result of--sizeof equals the number of bytes of memory that the object or type occupies, so let's look at the memory allocations for S1:
S1 S1 = {A, 0xFFFFFFFF};
After defining the above variables, add breakpoints, run the program, observe the memory where the S1 is located, what do you find?
Take my VC6.0 for example, S1 's address is 0x0012ff78, and its data is as follows:
0012ff78:61 cc CC FF FF FF FF
What did you find out? How is the 3-byte cc in the middle? Check out the instructions on MSDN:
When applied to a structure type or variable, sizeof returns the actual size,
Which may include padding bytes inserted for alignment.
So this is the legendary byte alignment! An important topic came up. Why do I need byte alignment? The principle of computer composition teaches us that this helps to speed up the number of computers, otherwise we have to spend more instruction cycles. To do this, the compiler will handle the struct by default (as well as data variables elsewhere), so that the base data type of 2 (short, etc.) is located at an address divisible by 2, and the base data type (int, etc.) with a width of 4 is at an address divisible by 4 and so on. In this way, the number of bytes in the middle of the two may need to be added, so the sizeof value of the entire struct increases. Let's swap the position of char and int in S1:
struct S2
{
int i;
char c;
};
Look at the results of sizeof (S2), how much is 8? Then look at the memory, the original member C still have 3 padding bytes, this is why AH? Don't worry, summarize the rules below.
Byte alignment details are related to compiler implementations, but in general, three guidelines are met:
1) The first address of a struct variable can be divisible by the size of its widest base type member;
2) the offsets (offset) of each member of the struct relative to the first address of the struct are an integer multiple of the member size, and if necessary, the compiler adds padding bytes between the members (internal adding);
3) The total size of the struct is an integer multiple of the size of the structure's widest base type member, and if necessary the compiler will add padding bytes (trailing padding) after the last member.
For the above guidelines, there are a few things to note:
1) The first is not to say that the address of a struct member is an integer multiple of its size, how is it said that the offset amount? Because of the existence of the 1th, we can only consider the offset of the member, so it is simple to think. Think about why. The offset of a member of a struct relative to the first address of the struct can be obtained by macro offsetof (), which is also defined in the 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 previously mentioned built-in data types such as char, short, int, float, double, where the "data width" refers to the size of its sizeof. Because a member of a struct can be a composite type, such as another struct, when looking for the widest base type member, you should include the child members of the compound type member instead of the composite member as a whole. However, when determining the offset position of a composite type member, the composite type is treated as a whole. Here is a bit of a mouthful, thinking about a bit, or let's take a look at the example (the specific values are still VC6 for example, no longer explained):
struct S3
{
Char C1;
S1 s;
Char C2
};
S1 the widest simple member of the type is INT,S3 when considering the widest simple type member is the S1 "break" see, so S3 the widest simple type is int, so that through S3 defined variables, its storage space first address needs to be divisible by 4, the entire sizeof (S3) value should be divisible by 4.
Is the offset of the C1 0,s? At this time S is a whole, it as the structure of the variable also satisfies the previous three criteria, so its size is 8, the offset is between 4,C1 and S will need 3 padding bytes, and C2 and S is not required, so the C2 offset is 12, the size of the C2 is 13,13 is not divisible by 4, It also has to fill 3 padding bytes at the end of the page. Finally, the value of sizeof (S3) is 16.
From the above narrative, we can get a formula:
The size of the struct is equal to the last member's offset plus its size plus the number of padding bytes at the end, namely:
sizeof (struct) = Offsetof (last item) + sizeof (last item) + sizeof (trailing padding)
Here, friends should have a new understanding of the structure of sizeof, but not too early, there is an important parameter affecting sizeof has not been mentioned, that is the compiler's pack instructions. It is used to adjust the structure alignment, different compiler name and usage slightly different, VC6 through the #pragma pack implementation, you can also directly modify the/zp compilation switch. The basic usage of the #pragma pack is: #pragma pack (n), n is a byte-aligned number with a value of 1, 2, 4, 8, 16, the default is 8, if this value is smaller than the sizeof value of the struct member, then the member's offset should be the value, that is, The offset of the struct member should take the minimum value of both, the formula is as follows:
Offsetof (item) = MIN (n, sizeof (item))
Look again at the example:
#pragma pack (push)//Save current pack settings to stack
#pragma pack (2)//must be used before structure 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 sizeof (i) equals 6 and can be divisible by 2, so the size of the entire S1 is 6. Similarly, for sizeof (S3), the offset of S is 2,c2 of 8, plus sizeof (C2) equals 9, cannot be divisible by 2, add a padding byte, so sizeof (S3) equals 10. Now, friends can easily take a breath, and also note that the "empty structure" (excluding data members) is not 0, but 1. Imagine how a "space-free" variable can be addressed, and how can two different "empty structure" variables be distinguished? As a result, the "empty struct" variable is also stored so that the compiler can allocate only one byte of space for the placeholder.
As follows:
struct S5 {};
sizeof (S5); Result is 1
8. sizeof with a bit domain structure
As mentioned earlier, bit-domain members cannot be given the sizeof value alone, and we are going to discuss the sizeof, which contains the structure of the bit domain, which is specifically listed for its particularity. C99 specifies that int, unsigned int, and bool can be used as bit field types, but almost all compilers extend this to allow the existence of other type types.
The primary purpose of using bit fields is to compress the storage, with the following approximate rules:
1) If the adjacent bit field field is of the same type and its bit width is less than the type sizeof size, the subsequent field will be stored next to the previous field until it cannot be accommodated;
2) If the adjacent bit field field is of the same type, but its bit width is greater than the type sizeof size, then the subsequent field will start from the new storage unit, and its offset is an integer multiple of its type size;
3) If the adjacent bit domain field type is different, the specific implementation of the compiler has a difference, VC6 take the non-compression method, dev-c++ take compression;
4) If the bit field fields are interspersed with non-bit field fields, no compression is performed;
5) The total size of the entire struct is an integer multiple of the size of the widest base type member.
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, the 1th byte can only hold the lower F1 and F2, so F2 is compressed into the 1th byte, and F3 only starts with the next byte. Thus the result of sizeof (BF1) is 2.
Example 2:
struct BF2
{
Char F1:3;
Short F2:4;
Char F3:5;
};
Due to the different types of neighboring bit fields, the sizeof is 6 in VC6 and 2 in dev-c++.
Example 3:
struct BF3
{
Char F1:3;
char F2;
Char F3:5;
};
Non-bit field fields are interspersed in which no compression is generated, and the size obtained in VC6 and Dev-c++ is 3.
9. SizeOf of the Consortium
Structs are sequential in memory organization, unions are overlapping, each member shares a memory, so sizeof, the entire consortium, is the maximum value of each member sizeof. Members of a struct can also be composite types, where composite type members are considered as a whole.
So, in the example below, the sizeof value of U equals sizeof (s).
Union U
{
int i;
char c;
S1 s;
};
Arrays are cast into struct pointers, and pointer problems within struct bodies