1. 程式人生 > >C++11 記憶體對齊 alignof alignas

C++11 記憶體對齊 alignof alignas

一 現象

先看一段程式碼:

struct s1
{
    char s;
    int i;
};

struct s2
{
    int i;
    double d;
};

cout << "-------basic type" << endl;
cout << "sizeof(char)	" << sizeof(char) << endl;
cout << "sizeof(int)	" << sizeof(int) << endl;
cout << "sizeof(double)	" << sizeof(double) << endl;

cout << endl;
cout << "-------struct" << endl;
cout << "sizeof(s1)	" << sizeof(s1) << endl;
cout << "sizeof(s2)	" << sizeof(s2) << endl;

結果如下:

不同機器環境,可能結果不同,但不影響說明問題。例如,結構體s1中包含一個char和int,那麼s1的大小應該是5,但結果是8,s2也是如此,這就涉及到一個概念:記憶體對齊。

二 記憶體對齊

1 什麼是記憶體對齊?

看到的一句說明,“資料項僅僅能儲存在地址是資料項大小的整數倍的記憶體位置上”。

2 為什麼要記憶體對齊?

(1)硬體原因,一些硬體平臺必須要求記憶體對齊,否則丟擲異常;另外涉及到不同平臺的移植問題。

(2)效能原因,對齊後訪問效率更高。

三 C++11 記憶體對齊實現

1 C++11 新引入操作符alignof對齊描述符alignas

基本對齊值 alignof(std::max_align_t)

alignas可以接受常量表達式和型別作為引數,可以修飾變數、類的資料成員等,不能修飾位域和用register申明的變數。一般往大對齊。

直接看一段程式碼(結合上一段程式碼):

struct s3
{
    char s;
    double d;
    int i;
};


struct s11
{
    alignas(16) char s;
    int i;
};

struct s12
{
    alignas(16) char s;
    int i;
};


// alignof
cout << "-------------------alignof---------------------" << endl;
// 基本對齊值
cout << "alignof(std::max_align_t)	" << alignof(std::max_align_t) << endl;
cout << endl;
cout << "-------basic type" << endl;
cout << "alignof(char)		" << alignof(char) << endl;
cout << "alignof(int)		" << alignof(int) << endl;
cout << "alignof(double)	" << alignof(double) << endl;

cout << endl;
cout << "-------struct" << endl;
cout << "alignof(s1)		" << alignof(s1) << endl;
cout << "alignof(s2)		" << alignof(s2) << endl;
cout << "alignof(s3)		" << alignof(s3) << endl;

cout << endl;
cout << endl;

// alignas
cout << "-------------------alignas---------------------" << endl;
cout << "alignof(s1)		" << alignof(s1) << endl;
cout << "alignof(s11)		" << alignof(s11) << endl;
cout << "alignof(s12)		" << alignof(s12) << endl;

cout << "sizeof(s1)    	" << sizeof(s1) << endl;
cout << "sizeof(s11)	" << sizeof(s11) << endl;
cout << "sizeof(s12)	" << sizeof(s12) << endl;

結果如下:

2 C++11還新增了幾個記憶體對齊的函式,每個函式有特定作用,此處不展開。

std::alignment_of
std::aligned_storage
std::max_align_t
std::align

四 C++98/03 記憶體對齊實現

此情況下主要是由編譯器實現,不同編譯器有不同方法。

1 MSVC

__declspec(align(#)),其#的內容可以是預編譯巨集,但不能是編譯期數值

#progma pack

__alignof

2 gcc

  __attribute__((__aligned__((#))))

 __alignof__