C語(yǔ)言中#pragma預(yù)處理指令的使用
一. pragma預(yù)處理指令概念
在所有的預(yù)處理指令中,#pragma指令可能是最復(fù)雜的了,它的作用是設(shè)定編譯器的狀態(tài)或者是指示編譯器完成一些特定的動(dòng)作。
二. pragma預(yù)處理指令的作用
#pragma指令對(duì)每個(gè)編譯器給出了一個(gè)方法,在保持與C和C++語(yǔ)言完全兼容的情況下,給出主機(jī)或操作系統(tǒng)專有的特征。依據(jù)定義,編譯指示是機(jī)器或操作系統(tǒng)專有的,且對(duì)于每個(gè)編譯器都是不同的。
#pragma為編譯器提供了一種在不同機(jī)器和操作系統(tǒng)上編譯以保持C和C++完全兼容的方法。
三. 預(yù)處理指令的參數(shù)
其格式一般為: #pragma para 其中para為參數(shù),下面來(lái)看一些常用的參數(shù)。
1)message參數(shù)
message參數(shù)是我最喜歡的一個(gè)參數(shù),它能夠在編譯信息輸出窗口中輸出相應(yīng)的信息,這對(duì)于源代碼信息的控制是非常重要的。其使用方法為:
#pragma message("HELLO WORLD")
message參數(shù)應(yīng)用
當(dāng)編譯器遇到這條指令時(shí)就在編譯輸出窗口中將消息文本打印出來(lái)。 當(dāng)我們?cè)诔绦蛑卸x了許多宏來(lái)控制源代碼版本的時(shí)候,我們自己有可能都會(huì)忘記有沒(méi)有正確的設(shè)置這些宏,此時(shí)我們可以用這條指令在編譯的時(shí)候就進(jìn)行檢查。假設(shè)我們希望判斷自己有沒(méi)有在源代碼的什么地方定義了_X86這個(gè)宏,可以用下面的方法:
#ifdef _X86 #pragma message("_X86 macro activated!") #endif
我們定義了_X86這個(gè)宏以后,應(yīng)用程序在編譯時(shí)就會(huì)在編譯輸出窗口里顯示X86 macro activated。我們就能夠記得自己定義的一些特定的宏了。
2)code_seg參數(shù)
它是另一個(gè)使用得比較多的pragma參數(shù),格式如:
#pragma code_seg( [ [ { push | pop}, ] [ identifier, ] ] [ "segment-name" [, "segment-class" ] )
它能夠設(shè)置程序中函數(shù)代碼存放的代碼段,當(dāng)我們開(kāi)發(fā)驅(qū)動(dòng)程序的時(shí)候就會(huì)使用到它。
push (可選參數(shù))將一個(gè)記錄放到內(nèi)部編譯器的堆棧中,可選參數(shù)可以為一個(gè)標(biāo)識(shí)符或者節(jié)名;
pop (可選參數(shù))將一個(gè)記錄從堆棧頂端彈出,該記錄可以為一個(gè)標(biāo)識(shí)符或者節(jié)名;
identifier (可選參數(shù))當(dāng)使用push指令時(shí),為壓入堆棧的記錄指派的一個(gè)標(biāo)識(shí)符,當(dāng)該標(biāo)識(shí)符被刪除的時(shí)候和其相關(guān)的堆棧中的記錄將被彈出堆棧;
segment-name (可選參數(shù))表示函數(shù)存放的節(jié)名。
//默認(rèn)情況下,函數(shù)被存放在.text節(jié)中 void func1() { // stored in .text } //將函數(shù)存放在.my_data1節(jié)中 #pragma code_seg(".my_data1") void func2() { // stored in my_data1 } //r1為標(biāo)識(shí)符,將函數(shù)放入.my_data2節(jié)中 #pragma code_seg(push, r1, ".my_data2") void func3() { // stored in my_data2 } int main() { }
3)once參數(shù)
#pragma once 用于保證頭文件只被編譯一次
#pragma once也是編譯器相關(guān)的,不一定被支持
#pragma once的效率比使用#ifndef更高。
由于有些編譯器支持 #pragma once,有些不支持,怎么做既能保證高效又能保證多個(gè)編譯器之間可以通用呢,可以混合使用 #ifndef 和 #pragma once
4)pack參數(shù)
它就是用于指定內(nèi)存對(duì)齊方式。編譯器在默認(rèn)情況下按照 4 字節(jié)對(duì)齊,也就是說(shuō)如果 #pragma pack() 不寫,則和 #pragma pack(4) 效果是相同的
這里是針對(duì)32位系統(tǒng),對(duì)于64位系統(tǒng)而言,默認(rèn)情況下按照8字節(jié)對(duì)齊。
許多實(shí)際的計(jì)算機(jī)系統(tǒng)對(duì)基本類型數(shù)據(jù)在內(nèi)存中存放的位置有限制,它們會(huì)要求這些數(shù)據(jù)的首地址的值是某個(gè)數(shù)k(通常它為4或8)的倍數(shù),這就是所謂的內(nèi)存對(duì)齊,而這個(gè)k則被稱為該數(shù)據(jù)類型的對(duì)齊模數(shù)(alignment modulus)。
Win32平臺(tái)下的微軟C編譯器(cl.exe for 80x86)在默認(rèn)情況下采用如下的對(duì)齊規(guī)則: 任何基本數(shù)據(jù)類型T的對(duì)齊模數(shù)就是T的大小,sizeof(T)。比如對(duì)于double類型(8字節(jié)),就要求該類型數(shù)據(jù)的地址總是8的倍數(shù),而char類型數(shù)據(jù)(1字節(jié))則可以從任何一個(gè)地址開(kāi)始。
5) section指令參數(shù)
#pragma section指令可用于創(chuàng)建一個(gè)自定義分區(qū),可以將全局變量或者函數(shù)放在這個(gè)自定義分區(qū)內(nèi)部,實(shí)現(xiàn)各個(gè)模塊之間的數(shù)據(jù)共享。
對(duì)于GNU C/C++編譯器來(lái)說(shuō),直接使用__attribute__((section(“xxx”)))對(duì)變量或函數(shù)進(jìn)行修飾即可自動(dòng)創(chuàng)建好分區(qū),將變量和函數(shù)放入對(duì)應(yīng)分區(qū)。而在windows 的VC編譯器下,必須結(jié)合#pragma section和__declspec(allocate(“xxx”))兩個(gè)指令才能實(shí)現(xiàn)該功能。
6)warning(…)參數(shù)
啟用編譯器警告消息的行為和選擇性修改,語(yǔ)法為:
#pragma warning( disable : 4507 34; once : 4385; error : 164 ) //這1行跟下面3行效果一樣 #pragma warning( disable : 4507 34 ) //不發(fā)出4507和34警告,即有4507和34警告時(shí)不顯示 #pragma warning( once : 4385 ) //4385警告信息只報(bào)告一次 #pragma warning( error : 164 ) //把164警告信息作為一個(gè)錯(cuò)誤
warning( push )指令存儲(chǔ)每個(gè)警告的當(dāng)前警告狀態(tài)。
warning( push, n)指令存儲(chǔ)每個(gè)警告的當(dāng)前狀態(tài)并將全局警告級(jí)別設(shè)置為 n。warning( pop )指令 彈出推送到堆棧上的最后一個(gè)警告狀態(tài)。
在push和pop之間對(duì)警告狀態(tài)所做的任何更改都將被撤消。
當(dāng)你編寫頭文件時(shí),你能用push和pop來(lái)保證任何用戶修改的警告狀態(tài)不會(huì)影響正常編譯你的頭文件。在頭文件開(kāi)始的地方使用push,在結(jié)束地方使用pop。
在使用標(biāo)準(zhǔn)C++進(jìn)行編程的時(shí)候經(jīng)常會(huì)得到很多的警告信息,而這些警告信息都是不必要的提示,所以我們可以使用#pragma warning(disable:xxxx)來(lái)禁止該類型的警告。
7)comment參數(shù)
#pragma comment(comment-type [,“commentstring”])
該指令將一個(gè)注釋記錄放入一個(gè)對(duì)象文件或可執(zhí)行文件中。
comment-type 是一個(gè)預(yù)定義的標(biāo)識(shí)符(如下所述,一共5個(gè)),它指定了注釋記錄的類型。 可選 commentstring 是一個(gè)字符串,它提供了某些注釋類型的附加信息。 由于 commentstring 是一個(gè)字符串,因此它遵循有關(guān)轉(zhuǎn)義字符、嵌入的引號(hào) (") 和串聯(lián)的字符串的所有規(guī)則。
8)其他pragma的參數(shù)
#pragma resource ".dfm"表示把.dfm文件中的資源加入工程。*.dfm中包括窗體外觀的定義。
#pragma hdrstop表示預(yù)編譯頭文件到此為止,后面的頭文件不進(jìn)行預(yù)編譯。
四. 預(yù)處理指令的總結(jié)
#pragma用于指示編譯器完成一些特定的動(dòng)作
#pragma所定義的很多指示字是編譯器特有的(后面的參數(shù)決定)
#pragma在不同的編譯器間是不可移植的
預(yù)處理器將忽略它不認(rèn)識(shí)的#pragma指令
不同編譯器可能以不同的方式解釋同一條 #pragma指令
到此這篇關(guān)于C語(yǔ)言中#pragma預(yù)處理指令的使用的文章就介紹到這了,更多相關(guān)C語(yǔ)言 #pragma預(yù)處理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語(yǔ)言中關(guān)于樹(shù)和二叉樹(shù)的相關(guān)概念
這篇文章主要介紹了Java?數(shù)據(jù)結(jié)構(gòu)之樹(shù)和二叉樹(shù)相關(guān)資料,文中通過(guò)示例代碼和一些相關(guān)題目來(lái)做介紹,非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-02-02Qt結(jié)合libqrencode生成二維碼的實(shí)現(xiàn)示例
本文主要介紹了Qt結(jié)合libqrencode生成二維碼的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01關(guān)于嘗試開(kāi)發(fā)PHP的MYSQL擴(kuò)展的使用
本篇文章小編將為大家介紹,關(guān)于嘗試開(kāi)發(fā)PHP的MYSQL擴(kuò)展的使用,需要的朋友可以參考一下2013-04-04詳解C++標(biāo)準(zhǔn)庫(kù)中處理正則表達(dá)式的類std::regex
std?是?C++?標(biāo)準(zhǔn)庫(kù)的命名空間,包含了大量標(biāo)準(zhǔn)的?C++?類、函數(shù)和對(duì)象,這些類和函數(shù)提供了廣泛的功能,包括輸入輸出、容器、算法、字符串處理等,這篇文章主要介紹了C++標(biāo)準(zhǔn)庫(kù)中提供的用于處理正則表達(dá)式的類std::regex,需要的朋友可以參考下2024-03-03OpenCV4 實(shí)現(xiàn)背景分離的詳細(xì)步驟(背景減法模型)
背景分離(BS)是一種通過(guò)使用靜態(tài)相機(jī)來(lái)生成前景掩碼(即包含屬于場(chǎng)景中的移動(dòng)對(duì)象像素的二進(jìn)制圖像)的常用技術(shù),本文給大家介紹OpenCV4 實(shí)現(xiàn)背景分離的詳細(xì)步驟,需要的朋友可以參考下2021-09-09