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环境下始终用寄存器传参

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