C字符串标准库、memset和丢弃的volatile关键字



我在xc32编译器(基于gcc的微控制器编译器,非开源(上收到这样的警告。

modem_uart.c:66:5:警告:传递"memset"的参数1将丢弃指针目标类型的"volatile"限定符[默认启用]

这是代码:

#include <string.h>
// (...)
volatile char rxbuf[MODEM_UART_RXBUF_SIZE];
// (...)
void some_function(void)
{    
// (...)
memset(rxbuf, 0, MODEM_UART_RXBUF_SIZE); // <- warning here
// (...)
}

有人能解释一下编译器为什么丢弃volatile吗?

memset标准中的规范有以下声明:

void *memset(void *s, int c, size_t n);

第一个参数未声明为volatile void *s。因此,它不能保证遵守访问volatile数据的额外限制。使对memset()的每次调用都将目的地视为易失性,这会对性能造成不必要的影响。

如果您需要这些保证,您应该用显式循环替换memset()调用。

for (int i = 0; i < MODEM_UART_RXBUF_SIZE; i++) {
rxbuf[i] = 0;
}

如果您在代码中的多个位置需要这个,您可以将它放入volatile_memset()函数中。

您的平台没有提供memset函数,该函数保证尊重它为volatile提供的任何保证。因此,为了调用memset,编译器必须丢弃rxbuf上的volatile限定符。

您可能应该编写自己的memset实现,该实现尊重volatile为您提供的任何保证。这个答案包括memcpy解决类似问题的答案。如果没有这样的保证,那么就去掉volatile

最新更新