16
volatile uint8_t reset_mask[768] = {0}

现在我在内部操作之一期间将此数组元素的值设置为 1。

在另一个函数调用中,我需要将此数组的所有元素设置为 0。一种方法是使用 for 循环,但我相信分配数组所有元素的更好方法是使用 memset

memset(reset_mask, 0, sizeof(reset_mask));

但我收到此错误:-“从类型 'volatile uint8_t* {aka volatile unsigned char*}' 类型转换为类型 'void*' 丢弃限定符”

如果我们不能在这里使用 memset,有没有更好的方法来一次性设置这个 volatile 数组的所有元素?

4

2 回答 2

8

您“可以”使用来memset消除易失性const_cast,但它会删除易失性语义。所以除非这对你没问题,否则你会被循环版本卡住。除非您的实现为您提供了一个 memset 版本,该版本采用 volatile* 并记录在案以完成您的工作。(我认为在嵌入式系统之外不太可能,即使在那里也会让我感到惊讶。)

于 2013-06-17T09:54:05.647 回答
5

正如 Balog Pal 所说,放弃volatile调用memset会破坏volatile语义。整体memset可能会被优化掉,或者发生未定义的行为不良。

要么编写你自己的循环来清零数组,要么使用这个memset_volatile

void memset_volatile(volatile void *s, char c, size_t n)
{
    volatile char *p = s;
    while (n-- > 0) {
        *p++ = c;
    }
}

realmemset也返回s并且cint,但这个版本对我来说更干净。

是否允许编译器优化此函数以一次写入多个字节尚不清楚,因此如果数组非常大,它可能会有点慢。

编辑:因为 C11 有memset_s。由于某种原因,它不需要指向 volatile 的指针,因此您必须丢弃 volatile。但是,可以保证实际覆盖内存。

于 2017-05-10T16:20:24.577 回答