用gdb理解C宏(#和##)
在Unix/Linux内核代码以及GNU libc源代码中,有两个C的宏被广泛使用。 例如:
/* glibc-2.25/sysdeps/powerpc/powerpc64/sysdep.h */
#define tostring(s) #s
#define stringify(s) tostring(s)
#define XGLUE(a,b) a##b
#define GLUE(a,b) XGLUE(a,b)
在gdb中用命令macro定义并展开看看,
(gdb) help macro
Prefix for commands dealing with C preprocessor macros. List of macro subcommands: macro define -- Define a new C/C++ preprocessor macro
macro expand -- Fully expand any C/C++ preprocessor macro invocations in EXPRESSION
macro expand-once -- Expand C/C++ preprocessor macro invocations appearing directly in EXPRESSION
macro list -- List all the macros defined using the `macro define' command
macro undef -- Remove the definition of the C/C++ preprocessor macro with the given name
...<snip>...
(gdb) #
(gdb) macro define tostring(s) #s
(gdb) macro define stringify(s) tostring(s)
(gdb) macro define XGLUE(a,b) a##b
(gdb) macro define GLUE(a,b) XGLUE(a,b)
(gdb) #
(gdb) macro list
macro define GLUE(a, b) XGLUE(a,b)
macro define XGLUE(a, b) a##b
macro define stringify(s) tostring(s)
macro define tostring(s) #s
(gdb) #
(gdb) macro expand tostring()
expands to: ""
(gdb) macro expand tostring("hello")
expands to: "\"hello\""
(gdb) #
(gdb) macro expand GLUE(, )
expands to:
(gdb) macro expand GLUE("hello", "world")
expands to: "hello""world"
由此可见,
- #是将单个宏参数转换成一个字符串
- ##则是将两个宏参数连接在一起
可以简记为“单#字符串,双#连接参”。
另外,也可以用"gcc -E"查看宏展开。例如,
$ cat foo.S
#define SYS_ify(syscall_name) __NR_##syscall_name
#define __NR_mmap 115
#define __NR_munmap 117 mov $SYS_ify(mmap), %eax
mov $SYS_ify(munmap), %eax $ gcc -E foo.S | tail -
mov $, %eax
mov $, %eax
$
用gdb理解C宏(#和##)的更多相关文章
- linux 内核(系统)、函数的理解、宏的程序调试
1.操作系统 1.1.Linux 内核(系统)的组成的部分: 内核主要有:进程调度.内存管理.虚拟文件系统.网络接口和进程通信五个部分组成. (1)进程调度 进程调度是CPU对多个进程对CPU访问的调 ...
- 理解C++ 宏
1.什么是宏,它解决什么问题? 宏的本质是文本替换,考虑下面的需求,程序中多次使用圆周率Pi,在每个地方都使用3.1415,显然很愚蠢.有没有好的办法呢?使用宏,如下: #define Pi 3.14 ...
- 深入理解UE4宏定义—— GENERATED_BODY
本文章由cartzhang编写,转载请注明出处. 所有权利保留. 文章链接:http://blog.csdn.net/cartzhang/article/details/72834164 作者:car ...
- 对 jiffies 溢出、回绕及 time_after 宏的理解
原文如下: 关于jiffies变量: 全局变量jiffies用来记录自启动以来产生的节拍的总数.系统启动时会将该变量初始化为0,此后,每当时钟中断产生时就会增加该变量的值.jiffies和另外 ...
- 对offsetof、 container_of宏和结构体的理解
offsetof 宏 #include<stdio.h> #define offsetoff(type, member) ((int)&((type*)0)->me ...
- 手把手教你玩GDB
第一部分牛刀小试:启动GDB开始调试 1. 编译带调试信息的可执行程序:用gcc(g++)编译的时候带上-g选项即可 2. 启动GDB开始调试 (1)gdb program ...
- iOS开发笔记--宏定义的黑魔法 - 宏菜鸟起飞手册
宏定义在C系开发中可以说占有举足轻重的作用.底层框架自不必说,为了编译优化和方便,以及跨平台能力,宏被大量使用,可以说底层开发离开define将寸步难行.而在更高层级进行开发时,我们会将更多的重心放在 ...
- 关于postgres中的一些宏的tips
Postgresql作为C语言开发的代码,其中大量的运用了一些宏的操作. 因此理解这些宏很重要,然而有时候这些宏总让人很费解. 作为一个经常翻翻postgresql源码的小白,在这里做一个记录吧,方便 ...
- Selenium IDE 宏 试用 一例
本质是宏(Macro)理念 Marco概念的广泛应用: 1.Office的Excel里的任何操作的 可以都可以用VBA编程记录下宏,然后把记录的宏,可以回放.当然也可以生成代码,比如给Excel设置单 ...
随机推荐
- MSP430 G2553 比较器Comparator_A+、数据流程图DFD、状态转换图STD
一.CA+构造 MSP430G2553带有一个比较器Comparator_A+(CA+),其构造框图如下图所示. 二.输入 & 输出 如上图所示,比较器有一个同向输入端(V+)和一个反向输入端 ...
- [Erlang26]怎么通过beam文件得到所有的record或源代码?
怎么通过beam文件得到所有的record或源代码? 1. 首先必须要在compile里面加上debug_info信息: 1 > c(load,[debug_info]). {ok,load ...
- 多次grep 没有看到输出
tail -f xxx.log | grep aaaa | grep bbbb 发现没有日志输出 但log中的那条记录包含aaaa 和 bbbb,就是说tail -f xxx.log | grep ...
- [idea]对于前端里面一些事情的看法
一些是自己的想法,另一些是看博客或者书籍里面得出的,随手记在这里. 基于页面的开发 最初的前端资源模式是基于页面的,像最开始接触web.开发web时候,一般是新建页面-引入jQuery-新建index ...
- Pi 实现VLC网络视频监控
安装摄像头 将Pi的原装摄像头安装在pi上面 ssh连接pi 通过xshell或者putty等工具连接ssh 安装VLC $ sudo apt-get update $ sudo apt-get in ...
- WEB文本框提示
<input type="text" placeholder="文本框提示语" name="version_no"/>
- 前端基础--css基本语法,选择器
一.css概述 CSS(Cascading Style Sheet)层叠样式表,定义如何显示HTML元素,给HTML设置样式,让它更加美观.当浏览器读到一个样式表,它就会按照这个样式表来对文档进行格式 ...
- Android性能测试-内存
前言: 近阶段都在探索android性能测试方面的东西,其中一个很重要的指标就是内存.对于内存,主要是一些gc是不是及时,或者说一些引用有没有及时释放,有没有导致oom或者内存持续增加导致卡顿,有没有 ...
- MySql数据库备份的几种方式
mysqldump工具备份 备份整个数据库 $> mysqldump -u root -h host -p dbname > backdb.sql 备份数据库中的某个表 $> mys ...
- “全栈2019”Java第八十五章:实现接口中的嵌套接口
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...