我想创建一个C宏,创建一个基于名称的函数

#define UNIQUE static void Unique_##__LINE__(void) {}

我希望它能扩展到像这样的东西:

static void Unique_23(void) {}

那是行不通的.使用令牌连接时,定位宏 被逐字逐句地对待,最终扩展到:

static void Unique___LINE__(void) {}

这可能吗?

推荐答案

问题是,当替换宏时,如果没有对预处理器应用字符串化运算符#或标记粘贴运算符##,则预处理器只会递归地扩展宏.因此,您必须使用一些额外的间接层,您可以使用令牌粘贴运算符和递归扩展的参数:

#define TOKENPASTE(x, y) x ## y
#define TOKENPASTE2(x, y) TOKENPASTE(x, y)
#define UNIQUE static void TOKENPASTE2(Unique_, __LINE__)(void) {}

然后,在UNIQUE的扩展过程中,__LINE__被扩展为行号(因为它既不涉及#也不涉及##),然后在TOKENPASTE的扩展过程中,令牌粘贴发生.

还应该注意的是,还有__COUNTER__宏,它在每次计算时都会扩展为一个新的整数,以防需要在同一行上有UNIQUE宏的多个实例化.注意:MS Visual Studio、GCC(从V4.3开始)和Clang支持__COUNTER__,但不是标准的C.

C++相关问答推荐

rSP堆栈指针在返回函数调用的值时有任何用途吗?

丑陋的三重间接:可扩展的缓冲区管理 struct

如何设置指针指向在函数中初始化的复合文字中的整数?

为什么复合文字(C99)的返回会生成更多的汇编代码?

如何将字符串argv[]赋给C中的整型数组?

有没有可能我不能打印?(C,流程)

在C++中头文件中声明外部 struct

有什么方法可以将字符串与我们 Select 的子字符串分开吗?喜欢:SIN(LOG(10))

为什么数组的最后一个元素丢失了?

在C中访问数组中的特定值

如何仅使用软件重新初始化STM32微控制器中的USB枚举?

为什么未初始化的 struct 的数组从另一个数组获取值?

在vfork()之后,链接器如何在不 destruct 父内存的情况下解析execve()?

在C中,为什么这个带有递增整数的main函数从不因溢出而崩溃?

在同一范围内对具有相同类型的变量执行的相同操作在同一C代码中花费的时间不同

";错误:寄存器的使用无效;当使用-masm=intel;在gcc中,但在AT&;T模式

使用 c 中的 write() 函数将非 ASCII 字符写入标准输出

10 个字节对于这个 C 程序返回后跳行的能力有什么意义

使用fread()函数读取txt文件

比 * 更快的乘法