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環境下始終用寄存器傳參