Language byte alignment analysis C

1 Introduction

What is byte-aligned it? Modern computer memory space is in bytes (byte) is divided, it seems that access to any type of variable can start from any address in theory, but the reality is often needed when accessing certain specific variable memory address is accessed, therefore, requires various types of data according to certain rules are arranged in space, rather than sequentially one after the discharge, which is byte aligned.

 

2, byte alignment benefits

Each hardware platform for the handling of storage space is very different, some platforms certain types of data can only be accessed from the start certain address, for example, some CPU architecture is not aligned variables in one visit when an error occurs, then the program must ensure that this architecture-byte aligned. Other platforms may not the case, but the most common is the failure to follow the requirements of the platform for its data storage alignment, will bring a loss in access efficiency, for example, some platforms are each read from the start even address, If an int (32-bit) variable holds in place even address the beginning, then a read cycle can be read 32bit, and if the local store at the beginning of an odd address, you need two read cycles, and read twice the results of the high and low bytes put together to get the 32bit data.

 

3, alignment criteria

There are four important basic concepts, as follows:

(1) itself alignment value data type: char data type is a self-aligned byte, short type data of 2 bytes, int / float type data is 4 bytes, double data type is 8 bytes;

(2) type structure or self alignment value: which value the maximum value of its members align itself;

(3) specify alignment value: when the value specified alignment value #pragma pack (value);

(4) the effective value data alignment members, structures, and the like: and their alignment value specified alignment value is smaller, namely:

Effective alignment values ​​align themselves = min {value} value currently assigned pack.

Wherein N is the effective value of the final alignment value used to determine the data storage address of the embodiment, N denotes the effective alignment "aligned on N", i.e., "hold the start address% N = 0" of the data.

 

In fact, the details of byte-aligned and closely related to the specific compiler implementation, but in general, satisfy the following three criteria:

First address (1) the structure of the variable to be divisible by its broadest size basic types of members;

Each member (2) offset with respect to the structure of the first address of the structure is an integer multiple of the size of the members, such as required, the compiler may add padding bytes between the members;

The total size (3) structure to the structure type of the widest base of an integer multiple of the size of the members, such as required, the compiler may add padding bytes after the last one member.

For the above three criteria are aligned as follows:

The first: the compiler when the structure to open up space, first find the widest structure of the basic data types, and then look for the memory address can be divisible by these basic types of location, and this address as the first address of the structure ;

Article: open space between a member of the structure, the pre-compiler first checks the address of the open space of the first address offset with respect to whether the structure is an integer multiple of the size of this member, if yes, storing the members, or , between this member and the upper member filled with a certain amount of bytes, in order to achieve an integral multiple of requirements;

Third: The total size of the structure that comprises the last byte of the padding member structural body satisfying the above two criteria are aligned, it also must meet the third criterion, otherwise it must be filled in the last few bytes meet the last criterion.

 

4, an example of byte alignment structure

Then give a simple example of a byte-aligned structure, and analyzed:

Sample code is as follows:

#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>

struct s {
    char a;
    short b;
    char c;
    int d;
    char e[3];
};

int main(int argc, char *argv[])
{
    printf("sizeof(struct s):%zd\n", sizeof(struct s));
    printf("offsets->a:%zd; b:%zd; c:%zd; d:%zd; e[0]:%zd; e[1]:%zd; e[2]:%zd\n",
                    offsetof(struct s, a), offsetof(struct s, b), 
                    offsetof(struct s, c), offsetof(struct s, d),
                    offsetof(struct s, e[0]), offsetof(struct s, e[1]),
                    offsetof(struct s, e[2]));

    exit(EXIT_SUCCESS);
}

Gcc compiler used to compile and run, outputs the result as follows:

Used in this test code offsetof macro, which can obtain the offset members in the structure, the operation results, we can see that, using the calculated structure sizeof total size of 16 bytes, if computed directly, then , char type is 1 byte, short type 2 bytes, int type accounted for 4 bytes, it should structure the size of 11 bytes, why the final size is 16 bytes it? Is due to the use of the above-described criteria byte aligned, analyze the following:

First, a variable occupation of type 1 byte char, short type variable b is, 2 bytes, according to the criterion 2, it is necessary to fill between 1 byte and a member b, c is a char type variable occupies 1 byte, a variable d is an int, 4 bytes, 2, 3 bytes needed to fill in between the guidelines members d and c, e is an array of type char, occupies 3 bytes, but according to the criteria 3, it is necessary in the last 1-byte padding, therefore, the total size of the structure should be 16 bytes.

 

5, change the alignment

By default, C compiler or variable for each data unit in their natural alignment condition distribution space, in general, the default may be changed by the following method for aligning conditions:

(1) using the directive #pragma pack (n): C compiler will be aligned on an n bytes;

(2) using the directive #pragma pack (): Cancel customized byte alignment;

In addition, the GCC-specific syntax

(3) __ attribute __ ((aligned (n))): Let structure member acts aligned on the n-byte natural boundaries, if the structural body members of a length greater than n, then according to the length of the largest member to align;

(4) __ attribute __ ((packed)): Cancel structure optimization in the compilation process alignment, are aligned according to the number of bytes actually occupied.

 

Below change the alignment explain some examples:

Use #pragma pack () the alignment structure change, as follows:

#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>

#pragma pack(1)
struct s {
    char a;
    short b;
    char c;
    int d;
    char e[3];
};
#pragma pack()

int main(int argc, char *argv[])
{
    printf("sizeof(struct s):%zd\n", sizeof(struct s));
    printf("offsets->a:%zd; b:%zd; c:%zd; d:%zd; e[0]:%zd; e[1]:%zd; e[2]:%zd\n",
                    offsetof(struct s, a), offsetof(struct s, b), 
                    offsetof(struct s, c), offsetof(struct s, d),
                    offsetof(struct s, e[0]), offsetof(struct s, e[1]),
                    offsetof(struct s, e[2]));

    exit(EXIT_SUCCESS);
}

Use gcc compiled to run the code, the following results:

Use #pragma pack (1) the byte alignment to byte 1, byte corresponds to cancel the default alignment, so the compiler will not be filled between the pair of variable byte, so the use of the sizeof () It is the actual size of the data type obtained occupied by 11 bytes.

 

When using #pragma pack (2) the byte alignment is set to 2 bytes, the result then?

#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>

#pragma pack(2)
struct s {
    char a;
    short b;
    char c;
    int d;
    char e[3];
};
#pragma pack()

int main(int argc, char *argv[])
{
    printf("sizeof(struct s):%zd\n", sizeof(struct s));
    printf("offsets->a:%zd; b:%zd; c:%zd; d:%zd; e[0]:%zd; e[1]:%zd; e[2]:%zd\n",
                    offsetof(struct s, a), offsetof(struct s, b), 
                    offsetof(struct s, c), offsetof(struct s, d),
                    offsetof(struct s, e[0]), offsetof(struct s, e[1]),
                    offsetof(struct s, e[2]));

    exit(EXIT_SUCCESS);
}

After using gcc compiler, and then run the following results: 

Can be seen, the overall size of the structure becomes 14 bytes, as follows:

1 is a variable align themselves, specify alignment value 2, value 1 is effectively aligned, assumed structure stored starting from the address 0, 1 = 0 line with 0%, the variable b is 2 align themselves, specify the alignment value of 2 , value of 2 is effectively aligned, stored starting from the address 2, in line with 2% 2 = 0, 1 byte needs to be filled between the variables b and a, align themselves variable c is 1, 2 is designated alignment, alignment effective is 2, 4 from the start address memory, meet 4% 2 = 0, the variable d is an int, a value of 4 align themselves, specify alignment value of 2, the effective value of 2 alignment, thus filling between the variable d 1 and c bytes, conform 6% 2 = 0, e array and so on, to the last member, since 2 bytes specify the alignment is required in the last 1-byte padding, so the total size of the structure is 14 bytes .

 

When using #pragma pack (8) is aligned with the specified structure body 8 happen? code show as below:

#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>

#pragma pack(8)
struct s {
    char a;
    short b;
    char c;
    int d;
    char e[3];
};
#pragma pack()

int main(int argc, char *argv[])
{
    printf("sizeof(struct s):%zd\n", sizeof(struct s));
    printf("offsets->a:%zd; b:%zd; c:%zd; d:%zd; e[0]:%zd; e[1]:%zd; e[2]:%zd\n",
                    offsetof(struct s, a), offsetof(struct s, b), 
                    offsetof(struct s, c), offsetof(struct s, d),
                    offsetof(struct s, e[0]), offsetof(struct s, e[1]),
                    offsetof(struct s, e[2]));

    exit(EXIT_SUCCESS);
}

Use gcc to compile and run the following results:

Can be seen that the total size of the structure is 16 bytes, and not be aligned on an 8-byte, 4-byte aligned but, because alignment following guidelines:

Effective alignment value = min {align themselves value, the current value specified pack}

Therefore, the above structure will be 4-byte aligned.

 

6, subsection

This paper introduces the alignment byte structure in C language, a description thereof will be substantially aligned with the guidelines and some specific examples.

 

reference:

http://www.baike.com/wiki/%E5%AD%97%E8%8A%82%E5%AF%B9%E9%BD%90

https://www.jianshu.com/p/f69652c7df99

https://www.cnblogs.com/clover-toeic/p/3853132.html

Guess you like

Origin www.cnblogs.com/Cqlismy/p/11440057.html