GNU計劃,又稱革奴計劃,是由Richard Stallman在1983年9月27日公開發(fā)起的。它的目標是創(chuàng)建一套完全自由的操作系統(tǒng),它在編寫Linux的時候自己制作了一個標準成為GNU C標準,但是作為GNU C一大特色的__attribute__機制卻為許多人所不知,現(xiàn)在讓我們一起走進__attribute__的世界,來揭開它的神秘面紗。
對于GNU C的__attribute__機制,它有什么神奇的作用呢?你們是不是已經(jīng)迫不及待了,對于__attribute__它可以修飾變量屬性和函數(shù)屬性,它的語法格式為:“__attribute__((參數(shù)));”,下面我們慢慢道來。
當我們初次學習一門語言的時候,都會寫一個很經(jīng)典的程序,沒錯就是在屏幕上輸出Hello world,現(xiàn)在對我們來說寫一段hello world程序,都是順手捏來的事了,那么你看過這樣的Hello world嗎?
#include
#include
__attribute__((constructor())) void pre_proc_1(void)
{
printf("\nhello world\n");
}
__attribute__((destructor())) void end_proc_1(void)
{
printf("\nHello World\n",__LINE__);
}
int main(int args,char **argv)
{
return 0;
}
可以猜到程序輸出什么結(jié)果嗎?沒錯也是輸出Hello world,直到為什么這樣嗎?細心的人肯定看到了在兩個子函數(shù)前面使用了__attribute__((constructor()))和__attribute__((destructor))來修飾子函數(shù),那么它們的作用是什么意思呢?被__attribute__((constructor()))修飾的函數(shù)在主函數(shù)前執(zhí)行,__attribute__((destructor()))修飾的函數(shù)在主函數(shù)后執(zhí)行,我們還可以在__attribute__((constructor(101)))在數(shù)字,括號中的數(shù)字代表函數(shù)的優(yōu)先級,這樣我們就可以安排我們函數(shù)執(zhí)行的順序了,一般0-100為系統(tǒng)使用,我們可以使用100以后的數(shù)字,在VC下也有這個屬性但是不能添加數(shù)字作為優(yōu)先級,但是我們可以安排我們函數(shù)的聲明順序來實現(xiàn)函數(shù)的執(zhí)行順序。
經(jīng)過一個簡單有意思的程序,下面我們繼續(xù)來說__attribute__機制,在前面說道__attribute__可以修飾變量和函數(shù)屬性,下面總結(jié)了如何使用__attribute__來修飾變量和函數(shù),讓我們一起來感受它的神奇。
函數(shù)屬性(1)__attribute__((format(archtype,string-index,first-to-check)));
format屬性告訴表達式按照printf,scanf,strftime,strfmom參數(shù)表格式規(guī)則對該函數(shù)的參數(shù)進行檢查。
例:
__attribute__((format(printf,m,n)));
__attribute__((format(scanf,m,n)));
m:第幾個參數(shù)為格式化字符
n;在參數(shù)集合中排在第幾
(2)__attribute__((noreturn));
該屬性通知編譯器從不返回值,當遇到類似函數(shù)需要返回值卻不可能運行到返回值就已經(jīng)退出的情況該屬性可以避免出現(xiàn)錯誤信息,例如C語言中的abort()和exit()函數(shù)就使用到了該屬性。
(3)__attribute__((const));
該屬性只能用于帶有數(shù)值類型參數(shù)的函數(shù)上,當反復調(diào)用帶有數(shù)值參數(shù)的函數(shù)時,由于返回值是相同的,所以編譯器可以進行優(yōu)化處理,除第一次需要運算外,其他只需返回第一次運行的結(jié)果,進而再快了執(zhí)行效率。
(4)Noinline & always_line
Nolinline為不內(nèi)聯(lián),always_line為總是內(nèi)聯(lián),我們在使用inline什么內(nèi)聯(lián)函數(shù)時,函數(shù)能否成為內(nèi)聯(lián)函數(shù),還要看編譯器的具體操作,使用noinline和always_line可以告訴編譯器是否執(zhí)行內(nèi)聯(lián)。
(5)看了前面的常用屬性,你們可能會問到可以在同一個函數(shù)中使用多個參數(shù)嗎?回答是肯定,并且這在實際中也是非常有用的。
變量屬性(1)__attribute__((aligned(n)));
例:
int a __attribute__((aligned(16))) = 0;
變量a將以16位對齊,我們也可以不加數(shù)字,如__attribute__((aligned));這樣編譯器會根據(jù)目標機器的情況實現(xiàn)對齊。它不僅可以修飾單個變量,也可以修飾符合變量如結(jié)構(gòu)體,聯(lián)合等,在實際中會用于修飾結(jié)構(gòu)體,是結(jié)構(gòu)體中的成員按一定的方式字節(jié)對齊。
(2)__attribute__((packed));
例:
int a[10] __attribute__((packed));
前面說了字節(jié)對齊屬性,有的編譯會默認使用一種字節(jié)對齊方式,假如我們不想使用字節(jié)對齊該怎么做呢?該屬性就起到了這個作用,使用packed可以取消字節(jié)對齊方式。
(3)__attribute__((at(address));
例:
int a __attribute__((at(0x00));
在一些特殊的情況,我們需要將某個變量存放特定的位置時,該屬性就起到了作用,該屬性的作用就是將變量a存儲到絕對地址為0x00的位置處。
(4)__attribute__((section(“section_name”)));
例如:
int a(void) __attribute__((seciton(abc));
說了前面的at屬性,現(xiàn)在我們來說seciton屬性,他和at有些相同,他的作用是將作用的函數(shù)或指定的數(shù)據(jù)放入指定名為Section_name的段中,一般在匯編文件中我們會使用到。
(5)__attribute__((cleanup(函數(shù)名)))
該屬性來修飾一個變量,當變量的作用域結(jié)束時,調(diào)用一個指定的函數(shù)。
例如:
void print()(printf(“\nend\n”);
void text()
{
Int a __attribute__((cleanup(print))) = 10;
}
看了這么多屬性的作用,大家是否感覺到了GNU編譯器的神奇呢?對于__attribute__關(guān)鍵字,大家是否有了更進一步的認識呢?
-
Linux
+關(guān)注
關(guān)注
88文章
11758瀏覽量
219009 -
操作系統(tǒng)
+關(guān)注
關(guān)注
37文章
7401瀏覽量
129282 -
編譯器
+關(guān)注
關(guān)注
1文章
1672瀏覽量
51595
原文標題:__attribute__ 你不知道的秘密
文章出處:【微信號:Zlgmcu7890,微信公眾號:周立功單片機】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
Linux系統(tǒng)中多個同類設備共用一套驅(qū)動
手機操作系統(tǒng)成功的秘密
關(guān)于國內(nèi)實時操作系統(tǒng)的接口標準統(tǒng)一
什么是UNIX操作系統(tǒng)呢
分享一套通用的開發(fā)環(huán)境搭建教程
Linux操作系統(tǒng)基本使用知識,Linux操作系統(tǒng)操作流程圖文詳解
Linux操作系統(tǒng)在定制PMP DM320的應用解析
微軟全新操作系統(tǒng)正在開發(fā) 或在5月Build大會亮相
APL庫是一套AS功能庫與OS操作對象的集合
一套完全自由的操作系統(tǒng)都有這個秘密
評論