C中的一级宏扩展
One level macro expansion in C
我在一个库中工作,该库是其他库的接口,具有多个已定义的宏,例如:
#define GPIOx some stuff
#define __HAL_RCC_GPIOx_CLK_ENABLE() some other stuff
其中 x 是一个字母 (A,B,C,...)。
我不能改变这些宏(或者我不应该改变它们,因为它们被其他组件使用)。
在我工作的库中,我试图定义一些用户可以修改的其他宏,例如:
#define DHT_GPIO_Port GPIOx
我想定义一个宏,它使用这样的定义来生成另一个宏名称:
#define __HAL_DHT_CLK_ENABLE(DHT_GPIO_Port) __HAL_RCC_## DHT_GPIO_Port ##_CLK_ENABLE()
这是因为我想为我的库使用宏而不是 __HAL_RCC_GPIOx_CLK_ENABLE(),因为它会根据用户定义的 GPIO 而有所不同。
但是,当我尝试使用我的 __HAL_DHT_CLK_ENABLE(DHT_GPIO_Port) 宏时,它会扩展为 __HAL_RCC_DHT_GPIO_Port_CLK_ENABLE(),而不是 __HAL_RCC_GPIOx_CLK_ENABLE()。
另一方面,我尝试将它放在另一个宏中,但它也扩展了 GPIOx,而我不需要。
也许,这是一个初学者的问题,但你能帮忙在另一个宏连接中只展开宏DHT_GPIO_Port的第一层吗?
以下应该有效:
#define __HAL_DHT_CLK_ENABLE_(DHT_GPIO_Port) __HAL_RCC_## DHT_GPIO_Port ##_CLK_ENABLE()
定义 __HAL_DHT_CLK_ENABLE(DHT_GPIO_Port) __HAL_DHT_CLK_ENABLE_(DHT_GPIO_Port)
例如下面一行:
__HAL_DHT_CLK_ENABLE(GpioA)
产生:
__HAL_RCC_GpioA_CLK_ENABLE()
没有太大意义。而不是无用的难以阅读的宏使用内联函数
#define SINLINE static inline __attribute__((always_inline))
SINLINE void __HAL_DHT_CLK_ENABLE(GPIO_TypeDef * const gpio)
{
switch((uint32_t)gpio)
{
case (uint32_t)GPIOA:
__HAL_RCC_GPIOA_CLK_ENABLE();
break;
case (uint32_t)GPIOB:
__HAL_RCC_GPIOA_CLK_ENABLE();
break;
case (uint32_t)GPIOC:
__HAL_RCC_GPIOA_CLK_ENABLE();
break;
}
}
当您启用优化并使用常量表达式调用它时(如 GPIOA
。GPIOB
等 switch ... case
将被优化。您还可以使用非常量调用它参数 - 你不能用宏来做。
避免像牙菌斑这样的宏。
我在一个库中工作,该库是其他库的接口,具有多个已定义的宏,例如:
#define GPIOx some stuff
#define __HAL_RCC_GPIOx_CLK_ENABLE() some other stuff
其中 x 是一个字母 (A,B,C,...)。
我不能改变这些宏(或者我不应该改变它们,因为它们被其他组件使用)。
在我工作的库中,我试图定义一些用户可以修改的其他宏,例如:
#define DHT_GPIO_Port GPIOx
我想定义一个宏,它使用这样的定义来生成另一个宏名称:
#define __HAL_DHT_CLK_ENABLE(DHT_GPIO_Port) __HAL_RCC_## DHT_GPIO_Port ##_CLK_ENABLE()
这是因为我想为我的库使用宏而不是 __HAL_RCC_GPIOx_CLK_ENABLE(),因为它会根据用户定义的 GPIO 而有所不同。
但是,当我尝试使用我的 __HAL_DHT_CLK_ENABLE(DHT_GPIO_Port) 宏时,它会扩展为 __HAL_RCC_DHT_GPIO_Port_CLK_ENABLE(),而不是 __HAL_RCC_GPIOx_CLK_ENABLE()。
另一方面,我尝试将它放在另一个宏中,但它也扩展了 GPIOx,而我不需要。
也许,这是一个初学者的问题,但你能帮忙在另一个宏连接中只展开宏DHT_GPIO_Port的第一层吗?
以下应该有效:
#define __HAL_DHT_CLK_ENABLE_(DHT_GPIO_Port) __HAL_RCC_## DHT_GPIO_Port ##_CLK_ENABLE()
定义 __HAL_DHT_CLK_ENABLE(DHT_GPIO_Port) __HAL_DHT_CLK_ENABLE_(DHT_GPIO_Port)
例如下面一行:
__HAL_DHT_CLK_ENABLE(GpioA)
产生:
__HAL_RCC_GpioA_CLK_ENABLE()
没有太大意义。而不是无用的难以阅读的宏使用内联函数
#define SINLINE static inline __attribute__((always_inline))
SINLINE void __HAL_DHT_CLK_ENABLE(GPIO_TypeDef * const gpio)
{
switch((uint32_t)gpio)
{
case (uint32_t)GPIOA:
__HAL_RCC_GPIOA_CLK_ENABLE();
break;
case (uint32_t)GPIOB:
__HAL_RCC_GPIOA_CLK_ENABLE();
break;
case (uint32_t)GPIOC:
__HAL_RCC_GPIOA_CLK_ENABLE();
break;
}
}
当您启用优化并使用常量表达式调用它时(如 GPIOA
。GPIOB
等 switch ... case
将被优化。您还可以使用非常量调用它参数 - 你不能用宏来做。
避免像牙菌斑这样的宏。