【Just For Fun】
本系列纯粹娱乐、研究用。一些旁门左道的东西。
事实上可能完全没用。 (๑•̀ω•́๑)
▌前置知识:
【Just For Fun】C - 预处理器、宏 #, ##、预先定义的宏
▌什么是 __COUNTER__
?
预定义宏 ( Predefined Macros ) 的其中之一,这是编译器拓展,gcc, vs 都支援。
根据某某 GCC.GNU 的文档,
This macro expands to sequential integral values starting from 0.
In conjunction with the ## operator, this provides a convenient means to generate unique identifiers.
Care must be taken to ensure that __COUNTER__ is not expanded prior to inclusion of precompiled headers which use it.
Otherwise, the precompiled headers will not be used.
__COUNTER__
是一个计数器,
会从 0
开始计数,然后每次调用加 1
,即:
__COUNTER__ // 0
__COUNTER__ // 1
__COUNTER__ // 2
通常配合 ##
使用,用于构建唯一的标识符(identifiers)。
▌建立唯一的变数名称:
做法其实很简单,把任意一个标识符与 __COUNTER__
合并就可以了。
有两种方法,中间层 / 延迟展开,先讲最普遍的 —— 中间层。
合并用的主体:
#define merge_body(a, b) a ## b //合并用的主体
因為 ##
的特性 ( 阻止另一个宏的展开 ),需要中间层:
#define merge(a, b) merge_body(a, b) //中间层
把标识符与 __COUNTER__
合并:
#define uniqueVarName(name) merge(name, __COUNTER__)
uniqueVarName()
就可以建立唯一的变数名称了。
▌使用延迟展开的方法:
还记得用于延迟展开的左括弧吗?
#define leftBracket (
使用这个的话,就可以把中间层去掉,然后 uniqueVarName()
变成这样:
#define uniqueVarName(name) merge_body leftBracket name, __COUNTER__)
更多相关及详细解释可以看看:【Just For Fun】C - 宏开发 - 真正按照参数数目展开不同的宏、延迟展开
/* ▌不想使用编译器拓展 ?*/
C 标准中有一些标准的预定义宏 ( Standard Predefined Macros ),其中:__LINE__
:从原始档开头起算,__LINE__
所在的行数。__func__
:函式名称 (C99) 。 同一个函式中不会有两个相同的行数,这意味:
#define uniqueVarName(name) merge( merge(name, __func__), __LINE__)__func__
+__LINE__
可以取替__COUNTER__
的作用。
不需要使用编译器拓展。
(经过测试,原来 __func__
是一个字串常量,
即在 main()
之中的 __func__
会被宣告为 "main"
(const char[]
) 而不是 main
,所以上面部分是错误的, 如果发现其他方法跟我说一下。 )
__
▌参考资料:
The C Preprocessor: Common Predefined Macros
GCC中常见预定义宏的使用 - 么刚的专栏 - CSDN博客
你应该掌握的#define宏定义 - 简书
c++ - Has anyone ever had a use for the __COUNTER__ pre-processor macro? - Stack Overflow
___
感谢阅读本文章! ~
___
【Just For Fun】俺 是 目 录 !