Предупреждение: указатель типа 'void *, используемый в арифметике

Я пишу и читаю регистры с карты памяти, например:

//READ
return *((volatile uint32_t *) ( map + offset ));

//WRITE
*((volatile uint32_t *) ( map + offset )) = value;

Однако компилятор дает мне следующие предупреждения:

warning: pointer of type ‘void *’ used in arithmetic [-Wpointer-arith]

Как я могу изменить свой код, чтобы удалить предупреждения? Я использую С++ и Linux.

Ответ 1

Так как void* является указателем на неизвестный тип, вы не можете делать арифметику указателя на нем, так как компилятор не знает, насколько велика указанная вещь.

Лучше всего сделать map типом, который является байтом, а затем выполнить арифметику. Вы можете использовать uint8_t для этого:

//READ
return *((volatile uint32_t *) ( ((uint8_t*)map) + offset ));

//WRITE
*((volatile uint32_t *) ( ((uint8_t*)map)+ offset )) = value;

Ответ 2

Тип void является неполным. Его размер неизвестен. Таким образом, арифметика указателя с указателями на пустоту не имеет смысла. Вы должны наложить указатель на тип void на указатель какого-либо другого типа, например, на указатель на char. Также учтите, что вы не можете назначить объект, объявленный с изменчивым квалификатором.

Ответ 3

Если использование арифметики на пустых указателях действительно то, что вам нужно, поскольку это стало возможным благодаря GCC (см. Арифметика на void- и Функциональные указатели), вы можете использовать -Wno-pointer-arith для подавления предупреждения.