我想创建一个C宏,创建一个基于名称的函数
#define UNIQUE static void Unique_##__LINE__(void) {}
我希望它能扩展到像这样的东西:
static void Unique_23(void) {}
那是行不通的.使用令牌连接时,定位宏 被逐字逐句地对待,最终扩展到:
static void Unique___LINE__(void) {}
这可能吗?
我想创建一个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.