Как установить изменчивый массив на ноль с помощью memset?

volatile uint8_t reset_mask[768] = {0}

Теперь я устанавливаю значения этих элементов массива в 1 во время одной из внутренних операций.

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

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

но я получаю эту ошибку: - "cast from type" volatile uint8_t * {aka volatile unsigned char *} 'для ввода' void * 'отбрасывает квалификаторы "

Если мы не можем использовать memset здесь, есть ли лучший способ установить все элементы этого изменчивого массива за один раз?

Ответ 1

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

Ответ 2

Как сказал Балог Пэл, отбрасывание 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, но эта версия для меня чище.

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

Изменение: С C11 есть memset_s. По какой-то причине не требуется указатель на volatile, поэтому вы должны выбросить volatile. Однако гарантированно перезаписать память.

Ответ 3

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

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

Для получения дополнительной информации о отливках проверьте следующее:

Регулярное литье против static_cast vs. dynamic_cast

С уважением

EDIT: Я добавил отсутствующую скобку. Я все равно не проверял это, хотя я думаю, что это должно сработать.