c++20中是否不推荐使用volatile限定符?
我刚刚在我的嵌入式项目中下载了带有 c++20 的 GCC 10。
然而,在嵌入式应用程序中,寄存器结构映射器使用 volatile 是很常见的。
由于编译器不知道寄存器值是否被 DMA 从外部更改,因此“强制”重新加载该寄存器是有意义的。
为了提高性能,其中一些 volatiles 被放置在 C 头文件中。当我在 cpp 文件中包含这些头文件时,我会收到很多不稳定的弃用错误。
有什么办法可以禁用这些错误吗?
@Edit 根据要求提供一些示例代码。
/*!
* @brief Enable the clock for specific IP.
*
* @param name Which clock to enable, see ref clock_ip_name_t.
*/
static inline void CLOCK_EnableClock(clock_ip_name_t name)
{
uint32_t regAddr = SIM_BASE + CLK_GATE_ABSTRACT_REG_OFFSET((uint32_t)name);
(*(volatile uint32_t *)regAddr) |= (1UL << CLK_GATE_ABSTRACT_BITS_SHIFT((uint32_t)name));
}
C:/xxx/kinetisSDK/2.7.0/devices/MK64F12/drivers/fsl_clock.h:671:37: error: compound assignment with 'volatile'-qualified left operand is deprecated [- Werror=volatile]
671 | (*(volatile uint32_t *)regAddr) |= (1UL << CLK_GATE_ABSTRACT_BITS_SHIFT((uint32_t)name)); |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
由于这些定义遍布 NXP SDK,因此我尝试仅提取必要的部分。
https://godbolt.org/z/WKzj5j
不过Godbolt好像没问题。也许是因为我将 gcc 10 用于 arm eabi。
回答
你不能再使用|=了,但你可以使用=,所以改变这个:
(*(volatile uint32_t *)regAddr) |= (1UL << CLK_GATE_ABSTRACT_BITS_SHIFT((uint32_t)name));
对此:
*(volatile uint32_t *)regAddr = *(volatile uint32_t *)regAddr | (1UL << CLK_GATE_ABSTRACT_BITS_SHIFT((uint32_t)name));
- @Lundin The standard doesn't define the behavior of `x |= y` if the value of `x` changes in ways the compiler doesn't know about during the execution of the operation anyway. You definitely can't write such code portably -- there's no such thing as a "portable UART flag register", it's a hardware quirk that requires platform-specific code. Your platform might guarantee that `|=` does the right thing, but it would be a platform-specific guarantee, not a C++20 one.