Стандартная библиотека строк C, memset и исключенное ключевое слово volatile

Я получаю подобное предупреждение на компиляторе xc32 (компилятор микроконтроллера на основе gcc, а не с открытым исходным кодом).

modem_uart.c:66:5: предупреждение: передача аргумента 1 из 'memset' отбрасывает квалификатор '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?

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() функция.

Ваша платформа не предоставляет memset функция, которая гарантированно соблюдает все гарантии, которые она предоставляет volatile. Итак, чтобы позвонить memset, компилятор должен отбросить volatile квалификатор на rxbuf.

Вам, вероятно, следует написать свою собственную реализацию memset уважает любые гарантии, которые вы ожидаете volatileчтобы обеспечить вас. Этот ответ включает один для memcpyрешить аналогичную проблему. Если таких гарантий нет, то избавьтесь от volatile.

Другие вопросы по тегам