前言
这一周一更来的有些晚了,但坚持下去总是好的。闲言少叙,前段时间在阅读redis以及libevent的源码时,GNU下的attribute属性出现在了日志函数以及结构体的定义中,因此在此一记。
知识点
下面给出的是使用了attribute的某些使用方法的示例代码。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#ifdef __GNUC__
#define ATTRIBUTE_FORMAT(a,b) __attribute__((format(printf,a,b)))
#define ATTRIBUTE_PACKED __attribute__((packed))
#else
#define ATTRIBUTE_FORMAT(a,b)
#define ATTRIBUTE_PACKED
#endif
struct a_st
{
int i;
char c;
int d;
};
struct b_st
{
int b_i;
char b_c;
int b_d;
}ATTRIBUTE_PACKED;
void log_error(int err, char *format, ...)ATTRIBUTE_FORMAT(2,3);
int main(int argc, char *argv[])
{
printf("a_st[%d]bytes b_st[%d]bytes\n", sizeof(struct a_st), sizeof(struct b_st));
if(argc < 2)
{
log_error(-1, "%s", "input args error");
}
return 0;
}
void log_error(int err, char *format, ...)
{
char buf[1024] = {0};
va_list ap;
va_start(ap, format);
vsnprintf(buf, sizeof(buf), format, ap);
va_end(ap);
(void)fprintf(stderr, "%s\n", buf);
exit(err);
}
在GNU中存在的attribute扩展了函数以及结构体的属性,在上述的代码中,当以以下的方式运行时:
[root@xxxxx]# ./log
输出的结果如下:
a_st[12]bytes b_st[9]bytes
input args error
可以看到,第一个在结构体的attribute的作用是取消结构体的优化对齐,当然,attribute同样也可以指定结构体的对齐方式,采用以下的方法则要求结构体采用8byte的对齐方式,更多的使用方法这就不赘述了。
attribute((aligned(8)))
对于函数后的attribute属性,这是使得函数在处理可变参数列表时按照printf的格式进行检查,当然,在编译的时候应该添加编译选项“-Wall”,否则此属性是无法生效的。
结束语
由于最近并未到什么问题,因此在阅读源码时假若看到感兴趣的东西,都会及时的在此分享。而对于attribute属性,当然不局限上面的这三种使用方法,感兴趣的同学可以继续深究学习,在这就不一一列举了。