1

我在 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 吗?

4

2 回答 2

2

标准中的规范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()函数中。

于 2020-10-05T19:45:30.910 回答
1

您的平台不提供memset保证尊重其提供的任何保证的功能volatile。因此,为了调用memset,编译器必须丢弃volatile限定符 on rxbuf

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

于 2020-10-05T19:45:14.793 回答