come from : 奔跑吧linux内核
宏内核架构的优点是设计简洁和性能比较好,而微内核架构的优势也很明显,比如稳定性和实时性等。
第二章 Linux内核基础知识
#define min(x, y) ({ \
typeof(x) _min1 = (x); \
typeof(y) _min2 = (y); \
(void) (&_min1 == &_min2); \
_min1 < _min2 ? _min1 : _min2; \
})
其中(void) (&_min1 == &_min2);有什么作用?
这句的作用是比较两个操作数的类型是否相同,防止不同类型的数据进行比较。
若不相同,则会在编译时给出警告:comparison of distinct pointer types lacks a cast。
两个指针类型不同是不能进行相互比较的。
struct line {
int length;
char contents[0]; // 变长数组
};
struct line *thisline = malloc(sizeof(struct line) + this_length);
thisline->length = this_length;
#include <linux/printk.h>
#define pr_debug(fmt, ...) \
dynamic_pr_debug(fmt, ##__VA_ARGS__)
...可变参数, __VA_ARGS__ 是编译器保留字段
预处理时把参数传递给宏,当宏调用展开时,实际参数就传递给dynamic_pr_debug函数了
int libcfs_debug_msg(struct libcfs_debug_msg_data *msgdata, const char *format1, ...)
__attribute__((format(printf, 2, 3));
__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)))是常用的,而另一种却很少见到。下面举例说明,其中myprint为自己定义的一个带有可变参数的函数,其功能类似于printf:
//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,...)