阅读代码时,经常会遇到预编译命令,有时我们自己写代码,也会使用,这样会程序编译更加灵活。其中预编译命令“#if defined()和#endif”,最为常见。
#if defined ()是C语言预处理器中的一个条件编译指令,用于检查某个宏是否已经被定义。这个指令的基本形式是:#if defined (macro),其中macro是你要检查的宏的名称。如果macro已经被定义,那么预处理器就会编译#if defined (macro)和#endif之间的代码。如果macro没有被定义,那么这部分代码将不会被编译。
1、举例如下:
#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */
#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U)
//如果“__Vendor_SysTickConfig”被定义过,且“__Vendor_SysTickConfig=0”,则参与编译
/**
\brief System Tick Configuration
\details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
Counter is in free running mode to generate periodic interrupts.
\param [in] ticks Number of ticks between two interrupts.
\return 0 Function succeeded.
\return 1 Function failed.
\note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
must contain a vendor-specific implementation of this function.
*/
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
{
return (1UL); /* Reload value impossible */
}
SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL);
/* set Priority for Systick Interrupt */
SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
return (0UL); /* Function successful */
}
#endif
显然上面的预编译条件满足,所以SysTick_Config()会被编译。
2、预编译条件满足还是灰色显示
MAK ARM编译器,在预编译条件满足时,“#if defined()和#endif”之间的代码,会被点亮;否则,会变为灰色。但也有特殊情况,编译器无法识别,但编译是可以通过的。举例如下:
在“stm32g474xx.h”中,见下图:
在“core_cm4.h”中,发现条件满足了,SysTick_Config()函数体还是灰色,这时,就要靠人脑去分析了,依赖编译器,无法解决问题。
遇到这种情况,只能靠人脑去分析了。
3、体验编译器的显示效果
1)、预编译条件不满足以灰色显示
2)、预编译条件满足以正常颜色显示