__attribute__关键字用来描述函数,变量和数据类型的属性,用于编译器对源代码的优化。
下面是对几种__attribute__属性的介绍:
1 __attribute__((deprecated))
deprecated:弃用. 如果在源文件在任何地方地方使用deprecated attribute函数,编译器将会发出警告.
<span style="font-size:18px;">#include <iostream>
using namespace std;
//
__attribute__((deprecated)) void test(int a)
{
return;
}
int main()
{
test(1);// output: void test(int a) is deprecated (declared at main.cpp:6)
return 0;
}
</span>
2 __attribute__ ((format))
该__attribute__属性可以给被声明的函数加上类似printf或者scanf的特征,它可以使编译器检查函数声明和函数实际调用参数之间的格式化字符串是否匹配。该功能十分有用,尤其是处理一些很难发现的bug。
format的语法格式为:
format (archetype, string-index, first-to-check)
format属性告诉编译器,按照printf, scanf, strftime或strfmon的参数表格式规则对该函数的参数进行检查。“archetype”指定是哪种风格;“string-index”指定传入函数的第几个参数是格式化字符串;“first-to-check”指定从函数的第几个参数开始按上述规则进行检查。
具体使用格式如下:
__attribute__((format(printf,m,n))) __attribute__((format(scanf,m,n)))
其中参数m与n的含义为:
m:第几个参数为格式化字符串(format string);
n:参数集合中的第一个,即参数“…”里的第一个参数在函数参数总数排在第几,注意,有时函数参数里还有“隐身”的参数,后面会提到;
在使用上,__attribute__((format(printf,m,n)))是常用的,而另一种却很少见到。
例如:
//m=1;n=2
extern void myprint(const char *format,...) __attribute__((format(printf,1,2)));
//m=2;n=3
extern void myprint(int l,const char *format,...) __attribute__((format(printf,2,3)));
需要特别注意的是,如果myprint是一个函数的成员函数,那么m和n的值可有点“悬乎”了,例如:
//m=3;n=4
extern void myprint(int l,const char *format,...) __attribute__((format(printf,3,4)));
其原因是,类成员函数的第一个参数实际上一个“隐身”的“this”指针。(有点C++基础的都知道点this指针,不知道你在这里还知道吗?)
<span style="font-size:18px;">#include <iostream>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
using namespace std;
void myprint(const char *format,...) __attribute__((format(printf,1,2)));
void myprint(const char *format,...)
{
return;
}
int main()
{
int a = 100;
int b = 200;
myprint("%s %d\n",a,b);
return 0;
}</span>
3 __attribute__ ((unused))
表示该函数或变量可能不使用,这个属性可以避免编译器产生警告信息。
4 __attribute__ ((sentinel))
参考http://www.guokr.com/post/160155/
5 __attribute__ ((visibility("hidden")))/__attribute__ ((visibility("default")))
visibility用于设置动态链接库中函数的可见性,将变量或函数设置为hidden,则该符号仅在本so中可见,在其他库中则不可见
如果外部模块没有定义,那么,将会调用这个弱符号,也就是在本地定义的func,相当于增加了一个默认函数。
原理:连接器发现同时存在弱符号和强符号,有限选择强符号,如果发现不存在强符号,只存在弱符号,则选择弱符号。如果都不存在:静态链接,恭喜,编译时报错,动态链接:对不起,系统无法启动。