使用 ## 和 __LINE__ 创建 C 宏(标记与定位宏的连接) [英] Creating C macro with ## and __LINE__ (token concatenation with positioning macro)

查看:21
本文介绍了使用 ## 和 __LINE__ 创建 C 宏(标记与定位宏的连接)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个 C 宏来创建一个基于名称的函数在行号上.我以为我可以做类似的事情(真正的函数会在大括号内有语句):

I want to create a C macro that creates a function with a name based on the line number. I thought I could do something like (the real function would have statements within the braces):

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

我希望将其扩展为:

static void Unique_23(void) {}

那行不通.使用令牌连接,定位宏按字面意思处理,最终扩展为:

That doesn't work. With token concatenation, the positioning macros are treated literally, ending up expanding to:

static void Unique___LINE__(void) {}

这可以吗?

推荐答案

问题是当你有一个宏替换时,预处理器只会在字符串化操作符 # 和令牌粘贴运算符 ## 应用于它.因此,您必须使用一些额外的间接层,您可以使用带有递归扩展参数的标记粘贴运算符:

The problem is that when you have a macro replacement, the preprocessor will only expand the macros recursively if neither the stringizing operator # nor the token-pasting operator ## are applied to it. So, you have to use some extra layers of indirection, you can use the token-pasting operator with a recursively expanded argument:

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

然后,__LINE__UNIQUE 的扩展过程中被扩展为行号(因为它不涉及 ###),然后在TOKENPASTE的扩展过程中进行token粘贴.

Then, __LINE__ gets expanded to the line number during the expansion of UNIQUE (since it's not involved with either # or ##), and then the token pasting happens during the expansion of TOKENPASTE.

还应该注意的是,还有 __COUNTER__ 宏,它在每次求值时扩展为一个新整数,以防您需要对 UNIQUE<进行多个实例化/code> 宏在同一行.注意:__COUNTER__ 受 MS Visual Studio、GCC(自 V4.3 起)和 Clang 支持,但不是标准 C.

It should also be noted that there is also the __COUNTER__ macro, which expands to a new integer each time it is evaluated, in case you need to have multiple instantiations of the UNIQUE macro on the same line. Note: __COUNTER__ is supported by MS Visual Studio, GCC (since V4.3), and Clang, but is not standard C.

这篇关于使用 ## 和 __LINE__ 创建 C 宏(标记与定位宏的连接)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆