GNU C對C的拓展之 特殊屬性申明

GNU C 允許使用特殊屬性對函數變量,類型修飾,以便對代碼進行手工優化和定製。在申明處加入關鍵字_attribute__((ATTRIBUTE))即可制定特殊屬性,如果存在多個屬性 要用逗號隔開。GNU C目前支持noreturn noinline always_inline pure const nothrow format format_arg no_instrument_function section constructor destructor used unused deprecated weak malloc aliaswarn_unused_result nonull等

首先看noreturn

#include <bits/stdc++.h>
#define ATTRIB_NORET __attribute__((noreturn))
using namespace std;
extern void printhello()ATTRIB_NORET;
extern void printhello(){
    printf("i have no return");
}

int noreturnfuncion (int n){
    if(n>0)
    {
       printhello();
    }
    else
    {
        return 1;
    }
}
int main()
{
     return noreturnfuncion(123);
    return 0;
}

當註釋掉attribute時在win10的GNU  會顯示

但當使用attribute時就不會顯示這個了,而是會顯示估計這個attribute是給默認返回了1

然後是packed屬性,它能夠取消結構在編譯時的對齊優化 


#define ATTRIB_NORET __attribute__((noreturn))
struct ex_struct{
    char emm;
    int emmm;
    char emmmm;
}__attribute__((packed));
struct ex2_struct{
    char emm;
    int emmm;
    char emmmm;
};
int main()
{
    struct ex_struct wdnmd;
    printf("%d\n%d\n",sizeof(struct ex_struct),sizeof(struct ex2_struct));
    return 0;
}

centOS7中的運行結果

 

最後寫一個regparm 它是用於制定寄存器傳參的個數,該屬性只用於函數定義和聲明中,如果參數超過規定的個數,剩餘參數將通過內存傳遞。

!regparm只在x86體系下有效,x64體系下無論是否採用regparm都用寄存器傳參。

#define REGPRAM0 __attribute((regparm(0)))
#define REGPRAM3 __attribute((regparm(3)))
int p=0;
int t1=1;
int t2=2;
int t3=3;
int t4=4;
void REGPRAM0 func1(int a)
{
	p=a+1;
}
void REGPRAM3 func3(int a,int b,int c,int d)
{
	p=a+b+c+d+1;
}
void  func3withoutRegparm(int a,int b,int c,int d)
{
	p=a+b+c+d+1;
}
int main(){
    func1(t1);
     func3(t1,t2,t3,t4);
   return 0;
}

可以用obidump -D regparm 反彙編一下然後看傳參  

發現當在x86環境下regparm參數有用  在x64環境下始終用寄存器傳參

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章