【问题标题】:How to force macro to not expand如何强制宏不展开
【发布时间】:2019-10-29 05:44:46
【问题描述】:

使用以下代码:

#include <stdio.h>

typedef struct
{
    int APB1ENR;
    int b;
    int c;
} RCC_TypeDef;

typedef struct
{
    int a;
    int b;
    int c;
} USART_TypeDef;

#define USART2_BASE                     0x1000
#define USART2                          ((USART_TypeDef *) USART2_BASE)
#define RCC_BASE                        0x2000
#define RCC_APB1ENR_USART2EN_Pos        (17U)
#define RCC_APB1ENR_USART2EN_Msk        (0x1UL <<   RCC_APB1ENR_USART2EN_Pos)
#define RCC_APB1ENR_USART2EN            RCC_APB1ENR_USART2EN_Msk
#define RCC                             ((RCC_Typedef *) RCC_BASE)
#define SET_BIT(REG, BIT)               ((REG) |= (BIT))
#define __HAL_RCC_USART2_CLK_ENABLE()   SET_BIT(RCC->APB1ENR, (RCC_APB1ENR_USART2EN))

#define UART_PERIPH     USART2

#define CONCATENATE(x)  // What comes here??

int main()
{
    CONCATENATE(UART_PERIPH);
    // | should expand to __HAL_RCC_USART2_CLK_ENABLE();
}

我们如何定义CONCATENATE(x) 宏以仅扩展一层深度。使用两级间接,它将一直扩展为指向结构的指针,我想要的是仅扩展 UART_PERIPH 一层并将其粘贴在一起以从其参数中形成一个已经存在的宏。

这可能吗?

【问题讨论】:

  • #define CONCATENATE(x) (x) 或只使用UART_PERIPH
  • 你想做的事情没有多大意义。假设有某种方式使CONCATENATE(UART_PERIPH) 仅扩展到第一级,即__HAL_RCC_USART2_CLK_ENABLE()。然后呢?
  • 澄清一下,因为我误解了这一点:他想使用UART_PERIPHUSART2 粘合到宏中,但USART2 已经被定义为其他东西。我认为这是不可能的,但我可能错了。
  • @yhyrcanus 没错。用 __HAL_RCC_ 宏粘合它。

标签: c gcc macros c-preprocessor


【解决方案1】:
我们如何定义 CONCATENATE(x) 宏以仅扩展一层深度。 ...这可能吗?

没有。这是您可用的。发生宏调用时,第一步是参数替换(a.s.;6.10.3.1);在该步骤中,如果在宏的替换列表中提及了参数中的标记,并且所述提及不涉及字符串化或粘贴,则评估参数中的标记。得到的扩展被替换列表中的所述参数替换。接下来,不按特定顺序应用字符串化/粘贴。最后,重新扫描和进一步替换(r.a.f.r; 6.10.3.4p1)发生,在此期间扫描生成的替换列表本身;在此扫描期间,宏的名称是“painted blue”(6.10.3.4p2;名称中没有提到“blue paint”而是technical jargon),这意味着如果遇到它,它将不会进一步扩展。

那么让我们从这个角度来看。 UART_PERIPH 是一个标识符。要么在某些上下文中被识别为宏(即,将触发宏调用),要么不会。上下文是否在 a.s. 期间无关紧要。或 r.a.f.r.;如果调用它,则调用涉及 r.a.f.r。 (没有 a.s. 因为它是类似对象的)。因此调用涉及获取USART2 并重新扫描它。不扩展USART2 的唯一可能方法是不将此标识符识别为宏,但由于它当前被定义为宏,因此发生这种情况的唯一方法是将此标识符涂成蓝色。这是不可能的(至少在预期的上下文中),因为USART2 必须扩展才能发生这种情况,到那时你已经注入了你不想要的令牌。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-18
    • 1970-01-01
    • 2017-07-24
    • 1970-01-01
    相关资源
    最近更新 更多