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

C string standard library, memset and discarded volatile keyword

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

modem_uart.c:66:5: warning: passing argument 1 of 'memset' discards 'volatile' qualifier from pointer target type [enabled by default]

代码如下:

#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 函数,该函数保证遵守它为 volatile 提供的任何保证。因此,为了调用 memset,编译器必须丢弃 rxbuf.

上的 volatile 限定符

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

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

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

第一个参数未声明 [​​=13=]。所以它不能保证遵守访问 volatile 数据的额外限制。使对 memset() 的每次调用都将目标视为易变的会造成不必要的性能影响。

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

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

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