Как установить энергозависимый массив в ноль, используя memset?

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 здесь, есть ли лучший способ установить все элементы этого энергозависимого массива за один раз?

13

Решение

Ты можешь использовать memset отторжение волатильности с const_cast, но это удалит изменчивую семантику. Так что, если это не подходит для вас, вы застряли с версией цикла. Если ваша реализация не дает вам версию memset, которая принимает volatile * и задокументирована для выполнения вашей работы. (Я думаю, что вряд ли за пределами встроенных систем, удивит меня даже там.)

6

Другие решения

Как сказал Балог Пал, отбрасывая 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;
}
}

Реальный memset также возвращает s а также c является int, но эта версия для меня чище.

Совершенно неясно, разрешено ли компилятору оптимизировать эту функцию для записи более одного байта за раз, поэтому, если массив очень большой, он может быть немного медленным.

3

Конечно, вы должны быть в состоянии использовать memset. Мне кажется, это проблема с приведением типа. По сравнению с C, C ++ довольно ограничен при использовании типов. Функция memset предполагает получение void *, но вы предоставляете uint8_t *. Попробуйте сделать это:

memset ( static_cast<void *>(reset_mask), 0, size_of(reset_mask) );

Для более подробной информации о кастингах проверьте это:

Обычное приведение против static_cast против dynamic_cast

С уважением

РЕДАКТИРОВАТЬ: я добавил пропущенные скобки. Я все равно не проверял это, хотя я думаю, что это должно работать.

-3
По вопросам рекламы [email protected]