A careful discussion of C + + byte alignment issues

Source: Internet
Author: User

The reason for byte alignment

To increase the storage speed of the CPU, the compiler optimizes the storage of the struct and union, which is byte-aligned.

Alignment

For structs or unions in a struct or union, their byte alignment standard is the number of bytes of data with the largest number of bytes in all its members.

In general, the number of bytes used by C + + variables

Char:1 bytes;

Short:2 bytes;

Int:4 bytes;

Long:4 bytes;

Long Long:8 bytes;

Float:4 bytes;

Double:8 bytes;

Bool:1 bytes;

The conditions to be met for byte alignment in *struct:

1. The offset of a variable's starting position relative to the starting position of the structure is an integer multiple of the byte number of the variable;

2. The total number of bytes occupied by the structure is an integer multiple of the number of bytes of the variable with the longest number of bytes in the struct.

Cases:

1 struct Struct 2 {3     Double D1; 4     Char D2; 5     int D3; 6 }a;

sizeof (a) = 8 + 1 + 3 + 4 = 16. The 3 bytes that are made up are an integer multiple of 4 for the starting position of the int data relative to the start position of the structure.

1 struct Struct 2 {3     Char D1; 4     Double D2; 5     int D3; 6 }b;

sizeof (b) = 1 + 7 + 8 + 4 = 20. 20/8 = 2 ... 4, so we need to make up 4 bytes, making it an integer multiple of 8.

Two conditions to be met for byte alignment in *union:

1, the size of the unoin must be sufficient to accommodate the widest members;

2. The size of the Union needs to be divisible by the size of the underlying member type it contains.

Another way to align bytes

VC provides #pragma pack (n) to customize byte alignment

There are two situations:

1, n is greater than the number of bytes of the variable: The offset only satisfies the default byte alignment;

2, n is less than the number of bytes of the variable: The offset is an integer multiple of n and does not use the default byte alignment.

Cases:

1 #pragmaPack (push)//Keep the alignment state2 #pragmaPack (4)//set to 4-byte alignment3 structTest4 {5     CharM1;6      Doublem2;7      intm3;8 }a;9 #pragmaPack (POP)//Restoring the Alignment stateTen sizeof(a) =1+3+8+4= -    //The three-bit is because N is less than 8, so the starting position of the M2 is N, or 4, relative to the start position of the structure. One  A  - #pragmaPack (8) - structS1 the { -     CharA; -     Longb; - }; + structS2 - { +     CharC; A     structS1 D; at     Long Longe; - }; - #pragmaPack () -  - sizeof(S1) =1+3+4=8 - sizeof(S2) =1+3+8+4+8= -。//The addition of 4 is because the byte number of the variable E is 8, and its offset from the starting position must be a multiple of 8. 

The discussion of the byte alignment problem has ended on the top. Here are some examples of the two topics I have come across:

1.

1#include <stdio.h>2 Union3 {4     Charx[5];5     inti;6 }a;7 8 intMain ()9 {Tena.x[0] =Ten; Onea.x[1] =1; Aprintf"%d\n", A.I); -printf"%d\n",sizeof(a)); -     return 0; the}

Output is 266 8

Analytical:

Allocating memory to the union involves byte-alignment issues, which are described in more detail here, and are simply explained here. The memory allocated by Union must be a multiple of all the base data types in the Union.
In this topic, which is a multiple of 1 and 4, and Char x[5] occupies 5 bytes, the size of the memory allocated by the Union should be 8 bytes.
The high-byte in the Windows system is after the low byte in front. Char X[5] has only the first two values, that is, two values are only 2 bytes, that is, the int data in the union is only low two bits on the value.
The binary representation of I is:
00000000 00000000 00000001 00001010
i.e.: 2^1 + 2^3 + 2^8 = 266
Also equivalent to 16 binary 0x010a, i.e.: 10 * 16^0 + 1 * 16^2 = 266

Here to add the conversion problem, also I collected:

Binary conversion

Decimal 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Hexadecimal 0 1 2 3 4 5 6 7 8 9 A B C D E F
Binary 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111

hexadecimal digits convert decimal digits:

0x2af5 Convert decimal:

5 * 16^0 = 5

F * 16^1 = 240

A * 16^2 = 2560

2 * 16^3 = 8192

---------------

5 + 240 + 2560 + 8192 = 10997

decimal digits convert hexadecimal digits:

2500 Convert Hex:

2500/16 = 156 ... 4

156/16 = 9 ... (C)

9/16 = 0 ... 9

----------------------

Get 4c9, reverse 9c4, that is, 2500 hexadecimal representation is: 0X9C4

Binary numbers convert hex digits:

101110011011.1001

Take the Si he method, that is, the binary decimal point is the dividing point, to the left (or right) every four bits.

After the component is good, the binary and hexadecimal number of the corresponding table, the four-bit binary by the right to add, the number is a hexadecimal number, and then in order, the position of the decimal point is unchanged.

The result is: b9b.9

It is important to note that when you take four bits to the left (or to the right), the highest bit (the lowest bit) is not able to make up four bits, you can fill the leftmost (or rightmost) of the decimal point by 0 to convert.

Hexadecimal numbers convert binary numbers:

The binary and hexadecimal number of the corresponding table, the hexadecimal number is divided into binary numbers, with four-bit binary numbers by the right to add, and finally get binary digits, the decimal point is still.

2.

1#include <iostream>2 using namespacestd;3 4typedefstructA5 {6     CharAchar;7     intaint_2;8      ShortaInt;9 }typea;Ten  OnetypedefstructB A { -     Charbchar[3]; - TypeA BA; the     Doublebdouble; - }typeb; -  - intMain () + { - TypeA A; + TypeB B; Acout <<sizeof(a) << Endl <<sizeof(b) <<Endl; at     return 0; -}

Output is 12 24

Analytical:

The answer to this question can easily be drawn from the discussion of the above byte alignment problem.
sizeof (TYPEA) = 1 + 3 + 4 + 2 = 10. 10/4 = 2 ... 2, it is necessary to fill 2 bytes, that is, sizeof (TYPEA) = 12;
sizeof (TYPEB) = 3 + 1 + 12 + 8 = 24. The 1 bytes are made up because the default alignment of the TypeA type in the struct TYPEB
is 4 bytes (that is, the byte size of int, which is the longest byte in the struct TypeA).

A careful discussion of C + + byte alignment issues

Related Article

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.