最近写一些东西,其中一些用到可变参数宏会非常方便
并且学习到了获得可变参数宏参数数量的方法,如下
[mw_shl_code=c,true]
#define __pm_arguments_expand(...) __VA_ARGS__
#define __pm_arguments_map(
_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17,
_18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, n, ...) n
#define __pm_arguments_count(...) __pm_arguments_expand(__pm_arguments_map(0, __VA_ARGS__,
32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17,
16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0))
[/mw_shl_code]
原理是通过参数位置差获得n位置的值,其值就是参数数量(我们传过去的)的值(vs下0个参数值为1,clang下0-32都正确)
有了这个我们就能写出可读性非常高的代码,并且只要定义mask和value就能非常清晰简单的操作寄存器了,看下面
[mw_shl_code=c,true]
typedef volatile pm_unsigned_integer_16_type pm_register_16_value_type;
typedef volatile pm_unsigned_integer_32_type pm_register_32_value_type;
typedef volatile pm_unsigned_integer_16_type *pm_register_16_type;
typedef volatile pm_unsigned_integer_32_type *pm_register_32_type;
#define __pm_register_16_maker(base, offset) ((pm_register_16_type)((base) + (offset)))
#define __pm_register_32_maker(base, offset) ((pm_register_32_type)((base) + (offset)))
#define pm_register_get(register, ...) (*(register) & __pm_arguments_join(|, , _mask, __VA_ARGS__))
#define pm_register_set(register, ...)
(*(register) = ((*(register)) & (~__pm_arguments_join(|, , _mask, __VA_ARGS__))) | __pm_arguments_join(|, , _value, __VA_ARGS__))
#define pm_register_FLASH_access_control __pm_register_32_maker(0x11, 0x0)
#define V1() //这是一个技巧,让编辑器能出现提示,又不会由于展开出现错误
#define V1_value 1
#define V1_mask 0x1 << 0
#define V2()
#define V2_value 2
#define V2_mask 0x1 << 1
#define V4()
#define V4_value 4
#define V4_mask 0x1 << 2
//#include <stdio.h>
void test() {
__pm_arguments_count();
pm_register_set(pm_register_FLASH_access_control, V1, V2, V4); // 这里相当于 *pm_register_FLASH_access_control = ((*pm_register_FLASH_access_control) & (~(7))) | 7;
}
[/mw_shl_code]
可以看到非常的清晰,代码中不会出现任何有疑问的值,且值定义起来也非常容易
以上在clang和vs上测试,且版本都是很新的,over
一周热门 更多>