是否有编译器指令来替换常量的一部分

Posted

技术标签:

【中文标题】是否有编译器指令来替换常量的一部分【英文标题】:Is there a compiler directive to replace part of a constant 【发布时间】:2012-04-11 20:10:42 【问题描述】:

我现在正在为微控制器使用嵌入式 C,我发现有时有几个外围设备只有一个字母不同(例如 UARTA、UARTB 等)。除了其他相同的寄存器的字母外,每个外围设备的代码通常都是相同的。例如,要设置外围设备 A,我会执行以下操作:

UCA2CTL1 |= UCSWRST;                      // Put state machine in reset
UCA2CTL0 |= UCSYNC+UCCKPL+UCMSB;          // 3-pin, 8-bit SPI slave
// Continue initializing peripheral registers with "A" in name

设置外设 B 的代码完全相同,只是寄存器名称由 1 个字母转置:

UCB2CTL1 |= UCSWRST;                      // Put state machine in reset
UCB2CTL0 |= UCSYNC+UCCKPL+UCMSB;          // 3-pin, 8-bit SPI slave
// Continue initializing peripheral registers with "B" in name

我希望能够更改目标外围设备,而无需#ifdef/复制/粘贴代码或查找/替换。是否有一些编译器指令或巧妙的技巧可以实现这种行为,这样我只需编写一次代码?我很想只 #define 外围设备中的最后一个字母,但类似的东西似乎危险地徘徊在靠近代码的地方对我来说很臭。

【问题讨论】:

你有什么理由不能在这里只使用一两个宏吗? @thelazydeveloper - 我很乐意,这就是我在这里的要求。 你实际上最好不要这样做。考虑“grep UCB2CTL1 *”来了解原因。 【参考方案1】:

这对你有用吗?

#define INITUC(device) \
UC ## device ## 2CTL1 |= UCSWRST; \
UC ## device ## 2CTL0 |= UCSYNC+UCCKPL+UCMSB
...
INITUC(A);
INITUC(B);

【讨论】:

【参考方案2】:

假设这些常量是 const 而不是 defines 你可以这样做:

#define MAKECONST(X) const int X ## 1; \
                     const int X ## 0; \
                     X ## 1 |= UCSWRST; \
                     X ## 0 |= UCSYNC+UCCKPL+UCMSB;

然后:

MAKECONST(UCA2CTL)
MAKECONST(UCB2CTL)

请注意,我的示例包括声明,我不知道您是否需要,如果不需要,请省略定义的前两行。例如:

#define SETUP(X) X ## 1 |= UCSWRST; \
                 X ## 0 |= UCSYNC+UCCKPL+UCMSB;

【讨论】:

以上是关于是否有编译器指令来替换常量的一部分的主要内容,如果未能解决你的问题,请参考以下文章

编译器是不是将给定常量参数的简单函数简化为唯一指令?

const常量类型

const和defin区别

什么是编译器中的常量传播?

C/C++中define定义的常量与const常量

CLIPS 常量编译器指令