pragma預處理分析

2021-06-16 16:18:43 字數 3043 閱讀 7327

#pragma是編譯器指示字,用於指示編譯器完成一些特定的動作

#pragma所定義的很多指示字是編譯器和作業系統特有的

#pragma在不同的編譯器間是不可移植的

預處理器將忽略它不認識的#pragma指令,當預處理器看到#pragma後,就不會像處理#define,#include那樣來進行進一步的處理,會把#pragma指令留給後續的編譯模組,編譯模組會根據他的引數執行一系列的動作,編譯模組如果發現parameter引數是自己支援的話,就按照自己的處理方式來進行處理,如果是自己不支援的話就直接忽略把它刪除掉。

兩個不同的編譯器可能以兩種不同的方式解釋同一條#pragma指令

一般用法:

#pragma  parameter

注:不同的parameter引數語法和意義各不相同,因為這依賴於編譯器製造商如何來實現

#pragma message

message引數在大多數的編譯器中都有相似的實現

message引數在編譯是輸出訊息到編譯輸出視窗中,單純的將訊息輸出,沒有更多含義

message可用於**的版本控制

注意:message是vc特有的編譯器指示字,gcc中將其忽略

以下程式在dev-c++中執行,編譯器是gcc

#include #if defined(android20)

#pragma message("compile android sdk 2.0...") //**版本控制,讓我們知道編譯的哪個版本

#define version "android 2.0"

#elif defined(android23)

#pragma message("compile android sdk 2.3...")

#define version "android 2.3"

#elif defined(android40)

#pragma message("compile android sdk 4.0...")

#define version "android 4.0"

#else

#error compile version is not provided!

#endif

int main()

直接編譯,會正常報錯

編譯選項加入巨集定義  -dandriod23,再編譯

但是在linux下編譯不會有#pragma的輸出

或許是gcc版本不一致造成的。

#pragma pack

記憶體對齊:

不同型別的資料在記憶體中按照一定的規則排列;而不是順序的乙個接乙個的排放,這就是對齊。

為什麼需要記憶體對齊?

cpu對記憶體的讀取不是連續的,而是分塊讀取的,塊的大小只能是1、2、4、8、16...2^n位元組

當讀取操作的資料未對齊,則需要兩次匯流排週期來訪問記憶體,因此效能會大打折扣

效率方面:

某些硬體平台只能從規定的位址處取某些特定型別的資料,否則丟擲硬體異常

編譯器優化後

#pragma pack能夠改變編譯器的預設對齊方式

#pragma pack(2)  //告訴編譯器不要按照預設方式對齊了,按照我指定的2位元組對齊方式對齊

struct test1

char c1;

short s;

char c2;                           //sizeof(struct test1) = 10

int i;

#pragma pack()  //編譯器將取消自定義位元組對齊方式

#pragma pack(4)  //告訴編譯器不要按照預設方式對齊了,按照我指定的4位元組對齊方式對齊

struct test2

char c1;

short s;

char c2;                              //sizeof(struct test1) = 12

int i;

#pragma pack()  //編譯器將取消自定義位元組對齊方式

struct占用的記憶體大小:

.第乙個成員起始於0偏移處如下c1起始於0

.每個成員按期型別大小和指定對齊引數n中較小的乙個進行對齊

.偏移位址和成員占用大小均需對齊

.結構體成員的對齊引數為其所用成員使用的對齊引數的最大值

.結構體總長度必須為所用對齊引數的整數倍,如下12(1+1+2+1+3+4)是1,2,4的整數倍

面試題:

在dev-c++中執行結果如下

但是在linux下執行結果如下

因為linux下gcc不支援8位元組對齊,只能支援1位元組,2位元組,4位元組對齊,所以這裡#pragma pack(8)編譯器直接無視,就按照預設的4位元組對齊,所以結果不一樣。

pragma 預處理指令

pragma 預處理指令詳解 在所有的預處理指令中,pragma 指令可能是最複雜的了,它的作用是設定編譯器的狀態或者是指示編譯器完成一些特定的動作。pragma指令對每個編譯器給出了乙個方法,在保持與c和c 語言完全相容的情況下,給出主機或作業系統專有的特徵。依據定義,編譯指示是機器或作業系統專有...

pragma 預處理命令

在所有的預處理指令中,pragma 指令可能是最複雜的了,它的作用是設定編譯器的狀態或者是指示編譯器完成一些特定的動作。pragma 指令對每個編譯器給出了乙個方法 在保持與c和 c 語言完全相容的情況下 給出主機或作業系統專有的特徵。依據定義 編譯指示是機器或作業系統專有的 且對於每個編譯器都是不...

pragma預處理詳解

在所有的預處理指令中,pragma 指令可能是最複雜的了,它的作用是設定編譯器的狀態或者是指示編譯器完成一些特定的動作。pragma指令對每個編譯器給出了乙個方法,在保持與c和c 語言完全相容的情況下,給出主機或作業系統專有的特徵。依據定義,編譯指示是機器或作業系統專有的,且對於每個編譯器都是不同的...