c - 这个来自内核代码的宏中的##是什么意思

标签 c macros linux-kernel

<分区>

我在一个内核代码中发现了这个宏.. http://lxr.free-electrons.com/source/arch/alpha/include/asm/io.h?v=3.0;a=arm#L140

#define IO_CONCAT(a,b)  _IO_CONCAT(a,b)
#define _IO_CONCAT(a,b) a ## _ ## b

我无法理解这个的意思。有人知道这个吗?

编辑:

然后这里返回什么

  return IO_CONCAT(__IO_PREFIX,readl)(addr);

最佳答案

双哈希用于将两个标记连接在一起:

#define CONCAT(a,b) a ## b

CONCAT(x, y) # Gives 'xy'

但是,当传递的参数之一是宏本身时,这种天真的实现不起作用:

#define Z y
CONCAT(x, Z) # Gives 'xZ', not 'xy' as one might expect

这就是为什么在您的问题中使用宏间接寻址的原因:

#define CONCAT(a,b)  __CONCAT(a,b)
#define __CONCAT(a,b) a ## b

#define Z y
CONCAT(x, Z) # Gives 'xy' 

更新。

现在考虑您要询问的具体示例:

return IO_CONCAT(__IO_PREFIX,readl)(addr);

这里的__IO_PREFIX显然是一个宏(Linux内核中的大写标识符通常是宏)。它在几个 places 中定义, one其中有:

#define __IO_PREFIX             generic

现在让我们看看采取了哪些步骤来扩展原始语句:

  1. 展开__IO_PREFIX:
    return IO_CONCAT(generic,readl)(addr);
    
  2. 展开IO_CONCAT(...):
    return _IO_CONCAT(generic,readl)(addr);
    
  3. 展开_IO_CONCAT(...):
    return generic_readl(addr);
    

关于c - 这个来自内核代码的宏中的##是什么意思,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12198663/

相关文章:

c++ - 如何找到一些宏的来源

c - 自旋锁初始化函数

c - C中的链表实现?

c - 多线程处理http请求时会发生奇怪的事情

C全局静态变量初始化是由链接器完成的?

c++ - 使用宏简化 C++ 代码。错误 : pasting "<" and "string" does not give a valid preprocessing token

arrays - Rust:数组长度的宏

c - 如何确定 union 中使用的是什么类型?

linux-kernel - 同时拥有 System.map 文件和/proc/kallsyms 需要什么?

c - 类函数宏的参数名称中的前导下划线是否有意义?