功能测试宏的参数必须是简单标识符_【Just For Fun】C - 宏开发 - 建立唯一的变数名称, __COUNTER__...

5d8533490e39e3ab2d8029b18673b466.png

【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】俺 是 目 录 !

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值