如何让static_assert将指针常量视为整数常量?解决GCC编译警告
解决GCC -Wpedantic下Static_assert指针比较的警告问题
在使用STM32 HAL库开发时,为了在编译期检查外设时钟源配置的正确性(即便后续复用功能变更),会添加static_assert做校验,但开启-Wpedantic编译选项后,编译器会抛出如下警告:
warning: expression in static assertion is not an integer constant expression [-Wpedantic]
示例代码如下:
/* Peripheral clock enable */ static_assert(DBG_UART==UART0, "cx32l003 hal: here need adjust."); __HAL_RCC_UART0_CLK_ENABLE(); static_assert(DBG_TX_GPIO_Port==GPIOD, "cx32l003 hal: here need adjust."); __HAL_RCC_GPIOD_CLK_ENABLE(); // both DBG_UART and UART0 refrence to same pointer constant: #define DBG_UART UART0 #define UART0 ((UART_TypeDef*) UART0_BASE) #define UART0_BASE 0x40000000UL
可行的解决方法
转换为地址数值比较
把指针强制转换为标准库的uintptr_t类型(需包含<stdint.h>),将指针比较转为整数常量比较,完全符合C标准对静态断言的要求:#include <stdint.h> static_assert((uintptr_t)DBG_UART == (uintptr_t)UART0, "cx32l003 hal: here need adjust."); static_assert((uintptr_t)DBG_TX_GPIO_Port == (uintptr_t)GPIOD, "cx32l003 hal: here need adjust.");uintptr_t是专门用来存储指针值的无符号整数类型,转换后比较的是地址的数值常量,-Wpedantic不会再触发警告。直接比较基地址宏
既然外设指针是基于基地址宏定义的,直接比较整数类型的基地址,从根源避免指针类型的问题:// 先定义对应调试外设的基地址宏 #define DBG_UART_BASE UART0_BASE #define DBG_TX_GPIO_BASE GPIOD_BASE static_assert(DBG_UART_BASE == UART0_BASE, "cx32l003 hal: here need adjust."); static_assert(DBG_TX_GPIO_BASE == GPIOD_BASE, "cx32l003 hal: here need adjust.");这种方式完全使用整数常量表达式,符合
-Wpedantic的校验规则。临时禁用指定警告
如果不想修改断言逻辑,可在静态断言代码块前后临时忽略-Wpedantic中关于常量表达式的警告,不影响其他代码的严格校验:#pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpedantic" static_assert(DBG_UART==UART0, "cx32l003 hal: here need adjust."); static_assert(DBG_TX_GPIO_Port==GPIOD, "cx32l003 hal: here need adjust."); #pragma GCC diagnostic poppush/pop会保存和恢复当前警告配置,仅对中间的代码生效。
内容的提问来源于stack exchange,提问作者flespark
相关产品推荐
相关产品推荐

