宏技巧解读

选自如下:http://wangcong.org/blog/archives/1821
情况是这样的:在 Linux 内核中,有一个函数 kmap_atomic(),它之前带两个参数,而现在,它的第二个参数已经名存实亡了,可以直接去掉。所以问题就出来了,如何警告使用 kmap_atomic() 的人带有两个参数的形式是过时的?换句话说,怎么才能在用两个参数调用 kmap_atomic() 时发出警告而用一个参数调用时就没有警告?

选用的技巧
https://lkml.org/lkml/2011/11/27/3

+
+#define PASTE(a, b) a ## b //预处理运算符# #为宏扩展提供了一种连接实际变元的手段
+#define PASTE2(a, b) PASTE(a, b)
+
+#define NARG_(_2, _1, n, ...) n //这里就是返回第三个参数的值,即是个数
+#define NARG(...) NARG_(__VA_ARGS__, 2, 1, :) //这里的处理很巧妙,如果参数是一个,就返回第三个1,如果参数是两个,就返回第三个2.处理巧妙
+
+static inline void *kmap_atomic(struct page *page)
+{
+ return __kmap_atomic(page);
+}
+
+static inline void __deprecated *kmap_atomic_deprecated(struct page *page,
+ enum km_type km)
+{
+ return __kmap_atomic(page);
+}
+
+#define kmap_atomic1(...) kmap_atomic(__VA_ARGS__)
+#define kmap_atomic2(...) kmap_atomic_deprecated(__VA_ARGS__)
+#define kmap_atomic(...) PASTE2(kmap_atomic, NARG(__VA_ARGS__)(__VA_ARGS__)) //这里处理也很巧,通过##相连,即如果传入1个参数,那么就是NARG返回1,就是kmap_atomic1(__VA_ARGS__),出入两个参数,就是kmap_atomic2(__VA_ARGS__),非常巧妙

另外

关注<<C语言编程艺术>>,<<C prime plus>>这两本基础书

对于可变参数部分及其反汇编探究,这里详细描述了

http://www.rainsts.net/article.asp?id=902
http://blog.csdn.net/linyt/article/details/2243605

原文地址:https://www.cnblogs.com/moonflow/p/2284080.html