问题描述
我想创建一个 C 宏来创建一个基于名称的函数行号上.我想我可以做类似的事情(真正的函数会在大括号内声明):
I want to create a C macro that creates a function with a name basedon 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 macrosare 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
的扩展过程中.
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 宏在同一行.注意:MS Visual Studio、GCC(自 V4.3 起)和 Clang 支持
__COUNTER__
,但不是标准 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 宏(与定位宏的标记连接)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!