attribute是GNU C特色之一。attribute可以设置函数属性,变量属性和类型属性。书写格式:
__attributr__(xxx)
1. 函数属性
aligned, alloc_size, noreturn, returns_twice, noinline, noclone, always_inline, flatten, pure, const, nothrow, sentinel, format, format_arg, no_instrument_function, no_split_stack, section, constructor, destructor, used, unused, deprecated, weak, malloc, alias, ifunc, warn_unused_result, nonnull, gnu_inline, externally_visible, hot, cold, artificial, error and warning.
format
给声明的函数加上类似printf或者scanf特征,使用编译器检查函数声明和函数实际调用参数之间的格式化字符串是否匹配。format参数使用如下:
format(archetype, string-index, first-to-check)
第一个参数传递“archetype”指定哪种风格,第二个参数“string-index”指定传递函数的第几个参数是格式化字符串;“first-to-check”指定第一个可变参数所在索引。
extern void myprint(const char *format,...) __attribute__((format(printf,1,2)));
extern void myprint(int l,const char *format,...)
__attribute__((format(printf,2,3)));
noreturn
例子:abort()和exit()。该属性通知编译器函数从不返回值。当遇到类似函数还未运行到return语句就需要退出来的情况,该属性可以避免出现错误信息。
extern void exit(int) __attribute__((noreturn));
extern void abort(void) __attribute__((noreturn));
availability
一个以逗号为分隔的参数列表,以平台的名称开始,包含一些放在附加信息里的一些里程碑式的声明。
__attribute__((availability(ios,introduced=2_0,deprecated=7_0,message=""__VA_ARGS__)));
introduced: 第一次出现的版本。
deprecated:声明要废弃的版本,意味着用户要迁移为其他api。
obsolete:声明移除的版本,意味着完全移除,再也不适用。
unavailable:这些平台不可用。
message:一些关于废弃和移除的额外信息,clang发出警告的时候会提供这些信息,对用户使用替代API非常有用。
这个属性支持的平台:ios,macos.
unavailability
知会编译器此方法不可用,如果强行调用,编译器提示错误。某个类在构造的时候不想直接通过init来初始化,只能通过特定的初始化方法()
#define CC_STTRIBUTE __attribute__((unavailable))
noinline & always_inline
内联函数:内联函数从源代码层看,有函数结构,编译后,不具备函数性质。内联函数不在调用时发生控制转移,在编译时将函数体嵌入到调用处。
内联的本质是用代码块直接替换函数调用处,使用场景:
A. 函数比较小;
B. 函数有性能要求,不经常调用;
void cc_function(int a)__attribute__((always_inline));
warn_unused_result
当函数或方法返回值很重要,调用者必须检查或使用返回值,否则编译器会发出告警.
int cc_function __attribute__((warn_unused_result))
constructor/destructor
构造器和析构器:construcor修饰的函数在main函数之前执行,destructor修饰的函数会在程序exit前调用。
#include <stdio.h>
#include <stdlib.h>
static __attribute__((constructor)) void before()
{
printf(" before~\n");
}
static __attribute__((destructor)) void after()
{
printf(" after~\n");
}
int main(int args,char ** argv)
{
return EXIT_SUCCESS;
}
2. 类型属性
aligned、packed、transparent_union、unused、deprecated、may_alias
int main(int argc __attribute__((unused)), char **argv)
{
return 0;
}
3. 变量属性
包含两种属性:aligned、paked
aligned(m) 将强制编译器尽其所能地确保变量在分配空间时采用m字节对齐方式。packed该属性对struct 或者union 类型进行定义,设定其类型的每一个变量的内存约束,当用在enum 类型定义时,暗示了应该使用最小完整的类型。aligned 属性使被设置的对象占用更多的空间,使用packed 可以减小对象占用的空间。
aligned
让所作用的结构成员对齐在n字节自然边界上。如果结构中有成员的长度大于n,则按照最大成员的长度来对齐。
typede struct {
char member1;
int member2;
short member3;
}__attribute__((aligned(1))) Family;
packed
让指定的接头体按照1字节对齐。常用于协议相关网络传输。
typedef struct {
char version;
short sid;
int len;
int64 time;
}__attribute__((packed)) header;
4.Clang特有
Clang是一个C语言,C++语言,Objective C语言轻量级编译器。
包含两种属性:availability、overloadable
availability
- introduced:声明被引入的第一个版本
- deprecated:声明被弃用的第一个版本,这意味着用户应该把这个API移走
- obsoleted: 声明被废弃的第一个版本,这意味着它将被完全移除并且不能再使用
- unavailable:声明在这个平台上将永远不可用
- message:额外的消息将被Clang提供当忽略一个警告或者一个错误在使用一个被弃用或者被废弃的声明。对引导用户替换APIs很有用。
void f(void) __attribute__((availability(macosx,introduced=10.4,deprecated=10.6,obsoleted=10.7)));
overloadable
定义若干个函数名相同,但参数不同的方法,调用时编译器会自动根据参数选择函数原型。在C中函数重载被引进使用overloadable属性。
#include <math.h>
float __attribute__((overloadable)) tgsin(float x) { return sinf(x); }
double __attribute__((overloadable)) tgsin(double x) { return sin(x); }
long double __attribute__((overloadable)) tgsin(long double x) { return sinl(x); }