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