C preproc:粘贴有效令牌和令牌值 [英] C preproc: pasting valid token and value of a token

查看:57
本文介绍了C preproc:粘贴有效令牌和令牌值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 STM32F1 微控制器,为此提供了一个标头,用于定义寄存器的位掩码和值,如下所示:

I am working with an STM32F1 microcontroller, for which a header is provided that defines bit masks and values for registers as follows:

#define RCC_CFGR_PLLMULL    //Mask of PLL multiplier setting bits
#define RCC_CFGR_PLLMULL1   //Value of PLL multiplier bits for PLL x1
#define RCC_CFGR_PLLMULL2   //Value of PLL multiplier bits for PLL x2
#define RCC_CFGR_PLLMULL3   //Value of PLL multiplier bits for PLL x3

等等等等

我想要做的是将我的 PLL 乘法器定义为一个整数,以便我可以使用它来导出时钟值 - 即 PLLCLK = IN_CLK * PLL_MULT - 并将该值粘贴到 RCC_CFGR_PLLMULL 获取正确的设置位.我通常为此使用的宏如下:

What I want to do is define my PLL multiplier as an integer so I can use it to derive the clock value - ie PLLCLK = IN_CLK * PLL_MULT - and paste the value onto RCC_CFGR_PLLMULL to obtain the correct setting bits. The macros I would normally use for this are as follows:

#define APPEND_VAL_HELPER(A, B)   A##B
#define APPEND_VAL(A, B)          APPEND_VAL_HELPER(A,B)

然后,如果我将 SOME_NUM 定义为 123:

Then if I define SOME_NUM as, say, 123:

#define FOO                       APPEND_VAL(BAR, SOME_NUM)

结果 FOO 定义为 BAR123.通常这是有效的.问题是:在这种情况下,RCC_CFGR_PLLMULL 在粘贴之前是一个有效的令牌.这导致它在 APPEND_VAL 的调用中扩展,我得到类似 ((uint32_t)0x003C0000)123 的东西.我不知道如何在不扩展 A 的情况下让 B 扩展,至少在 GCC 中是这样.有解决方法,但我正在寻找一个干净的解决方案.存在吗?

Results in the FOO defining as BAR123. Normally this works. Here's the problem: in this case, RCC_CFGR_PLLMULL is a valid token before being pasted. This results in it expanding in the invocation of APPEND_VAL and I get something like ((uint32_t)0x003C0000)123. I can't figure out how to get B to expand without also expanding A, at least in GCC. There are workarounds to this but I'm looking for a clean solution. Does it exist?

推荐答案

我不确定您认为什么是干净"的解决方案,但这对我有用,而且看起来还不错:

I'm not sure what you would consider a "clean" solution, but this works for me and doesn't seem too bad:

/* target header */
#define RCC_CFGR_PLLMULL         0x003C
#define RCC_CFGR_PLLMULL1        0x0003

/* pasting macros */
#define APPEND_VAL_HELPER(A, B)  A ## B
#define APPEND_VAL(A, B)         APPEND_VAL_HELPER(A, B)
#define RCC_CFGR(T, N)           APPEND_VAL(RCC_CFGR_, APPEND_VAL(T, N))

例如,您将其用作

#define FOO RCC_CFGR(PLLMUL, 1)

你也可以

#define BAR RCC_CFGR(PLLMUL, )

BAR定义为RCC_CFGR_PLLMUL(无尾).

显然,这是特定于可能的目标宏的子集,但它可以完成工作并且读取干净.据我所知,没有办法编写一个完全通用的标记粘贴宏——那些最通用的宏会遇到诸如您所描述的问题.

Obviously, this is specific to a subset of possible target macros, but it does the job and reads cleanly. To the best of my knowledge there is no way to write a fully general token-pasting macro -- those that are most general suffer from issues such as the one you described.

这篇关于C preproc:粘贴有效令牌和令牌值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆