[转]宏的高级使用--##,__VA_ARGS__, __FILE__, __FUNCTION__等
[转]宏的高级使用--##,__VA_ARGS__, __FILE__, __FUNCTION__等
http://blog.csdn.net/yiya1989/article/details/7849588
先说一下本文中会提到的内容:##,__VA_ARGS__, __FILE__, __LINE__ , __FUNCTION__等
宏变量:
先举一个例子,会用到上面这些宏:
- #define myprintf(...) printk("[lch]:File:%s, Line:%d, Function:%s," \
- __VA_ARGS__, __FILE__, __LINE__ ,__FUNCTION__);
此处的 #define 的作用是将 myprintf( )换成后面那一大串的内容,而括号内 ... 的内容原样抄写在 __VA_ARGS__ 的位置。最终输出如下:
[lch]:File:arch/arm/mach-omap2/board-omap3wscec-camera.c, Line:163, Function:beagle_cam_init,camera init!
解析:
1)__VA_ARGS__:总体来说就是将左边宏中 ... 的内容原样抄写在右边 __VA_ARGS__
所在的位置。它是一个可变参数的宏,是新的C99规范中新增的,目前似乎只有gcc支持(VC从VC2005开始支持)。要注意的是,printf
的输出格式是括号内左边是字符串,右边是变量,而且右变量与左输出格式是一一对应的。所以在上面那个例子中,
__VA_ARGS__只能是一些不含任何变量的字符串常量。因为上面的例子中若__VA_ARGS__含有变量,整个printf的输出与变量便不能一
一对应,输出会出错。
如果仅仅是替换函数名,可用如下方式,此时对__VA_ARGS__无任何特殊要求:#define myprintf(...) printk( __VA_ARGS__),在调试程序时可以这样用:
- #ifndef LOG_NDEBUG_FUNCTION
- #define LOGFUNC(...) ((void)0)
- #else
- #define LOGFUNC(...) (printk(__VA_ARGS__))
- #endif
2) __FILE__ :宏在预编译时会替换成当前的源文件名
3) __LINE__:宏在预编译时会替换成当前的行号
4) __FUNCTION__:宏在预编译时会替换成当前的函数名称
5)类似的宏还有 __TIME__,__STDC__, __TIMESTAMP__等,就完全当一个变量来使用即可。
宏连接符##:
举个例子:宏定义为#define XNAME(n)
x##n,代码为:XNAME(4),则在预编译时,宏发现XNAME(4)与XNAME(n)匹配,则令 n 为
4,然后将右边的n的内容也变为4,然后将整个XNAME(4)替换为 x##n,亦即 x4,故 最终结果为 XNAME(4) 变为 x4.
代码如下:
- #include <stdio.h>
- #define XNAME(n) x ## n
- #define PRINT_XN(n) printf("x" #n " = %d/n", x ## n);
- int main(void)
- {
- int XNAME(1) = 14; // becomes int x1 = 14;
- int XNAME(2) = 20; // becomes int x2 = 20;
- PRINT_XN(1); // becomes printf("x1 = %d,", x1);
- PRINT_XN(2); // becomes printf("x2 = %d/n", x2);
- return 0;
- }
输出为:x1 = 14, x2 = 20
PS:编译过程:
1,扫描解析文件
2,预处理(宏在此时处理,该替换的文字会被替换)
3,对处理过的源代码进行汇编,输出汇编语言的代码(C语言的控制流程被处理)
4,编译为二进制目标文件
5,与程序库进行链接,输出最终的程序文件
(宏 和 C语言在不同的阶段处理执行)
[转]宏的高级使用--##,__VA_ARGS__, __FILE__, __FUNCTION__等的更多相关文章
- C语言宏的高级应用
原文:C语言宏的高级应用 关于#和##在C语言的宏中,#的功能是将其后面的宏参数进行字符串化操作(Stringfication),简单说就是在对它所引用的宏变量通过替换后在其左右各加上一个双引号.比如 ...
- Visual Studio 宏的高级用法
因为自 Visual Studio 2012 开始,微软已经取消了对宏的支持,所以本篇文章所述内容只适用于 Visual Studio 2010 或更早期版本的 VS. 在上一篇中,我已经介绍了如何编 ...
- 34.Linux-printk分析、使用__FILE__, __FUNCTION__, __LINE__ 调试
本节学习目的 1)分析printk()函数 2)使用printk()调试驱动 1.在驱动调试中,使用printk(),是最简单,最方便的办法 当uboot的命令行里的“console=tty1”时,表 ...
- PHP __DIR__, __FILE__, __FUNCTION__, __CLASS__, __METHOD__, __LINE__, __NAMESPACE__
PHP has large number of predefined constants. This HOWTO will present the seven most important, most ...
- linux 中C语言便于调试的宏定义编写及 __FILE__,__FUNCTION__, __LINE__参数使用
转自:http://blog.csdn.net/edonlii/article/details/8491342/ 在linux编程中,当文件数量变的众多之后,使用gdb调试就是一场灾难.因此在程序中加 ...
- 可变参数宏__VA_ARGS__和...
__VA_ARGS__ 是一个可变参数的宏(gcc支持).实现思想就是宏定义中参数列表的最后一个参数为省略号(也就是三个点).这样预定义宏_ _VA_ARGS_ _就可以被用在替换部分中,替换省略号所 ...
- __VA_ARGS__可变参数宏
#define qWiFiDebug(format, ...) qDebug("[WiFi] "format" File:%s, Line:%d, Function:%s ...
- C Primer Plus(第五版)学习笔记-可变宏:...和__VA_ARGS__
一 .__VA_ARGS__ P454 所讲printf()这些输出函数的参数是可变的,在调试程序时,可能希望定义参数为可变的输出函数, 那么可变参数宏会是一个选择,例如: #define DEBUG ...
- __FUNCTION__, __LINE__ 有助于debug的宏定义
__FUNCTION__, __LINE__ 今天无意之间看到一段代码,里面有这样一个片段: if (!interface) { err ("%s - error, can't find d ...
随机推荐
- C++复习笔记
好多东西都忘了,现在重新复习一遍,把遇到的要点都记录下来.随时更新. 指针 C保证在为数组分配存储空间的时候,指向数组之后的第一个位置的指针也是合法的.也就是说保证指针 a + SIZE 是合法的,但 ...
- 【递归】油桶问题dp
问题 : [递归]油桶问题 题目描述 楚继光扬扬得意道:“当日华山论剑,先是他用黯然销魂掌破了我的七十二路空明拳,然后我改打降龙十八掌,却不防他伸开食指和中指,竟是六脉神剑,又胜我一筹.可见天下武学彼 ...
- 房间声学原理与Schroeder混响算法实现
一.混响时间的计算与预测 所谓混响就是声音的直达声与反射声很紧凑的重合在一起时人耳所听到的声音,这个效果在语音的后期处理时特别有用.能产生混响最常见的场景就是房间内,尤其是空旷的房间中. 混响有直达声 ...
- PF防火墙
PF防火墙 点击认领 PF防火墙 ( 全称:Packet Filter ) 是 UNIX LIKE 系统上进行 TCP/IP 流量过滤和网络地址转换的软件系统.PF 同样也能提供 TCP/ ...
- some smart
1.ca.laplanete.mobile.pageddragdropgridhttps://github.com/mrKlar/PagedDragDropGridPagedDragDropGrid ...
- 把txt文件中的json字符串写到plist文件中
- (void)json2Plist { NSString *filePath = [self applicationDocumentsDirectoryFileName:@"json&qu ...
- 容易网CEO陈从容:用分享成就生活之美
与客户分享便利,与员工分享成长,与生活分享愉悦.予人玫瑰,手有余香.“拥有值得分享的人和事物,亦有值得被分享的人和事物”,这就是陈从容对于美好生活的定义. 米色无袖洋装搭配同色系的单鞋配件,温柔的卷发 ...
- android四种更新UI的方法
笔记: // 使用handler.post(Runnable)更新UI public void updateUI_Fun1() { new Thread() { public void run() { ...
- How Old Are You?
今天要分享的是一个测年龄的小应用,就类似是http://how-old.net官网测年龄的功能一样,我的也是这样一个功能,细节捕获当然没有how-old多啦,不过这些主要是基于一个第三方的jar包,我 ...
- php学习笔记3--php中获取时间与实际时间不符
问题描述:在php脚本中使用date()获取服务器时间时总是与实际时间相差几个小时. 可能原因:php配置文件中时区的设置出现问题 解决方法: 方法1. php.ini文件中date.timezone ...