Стандартная библиотека строк 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
.