Предупреждение: указатель типа 'void *' используется в вычитании - PullRequest
5 голосов
/ 26 апреля 2010

Несмотря на то, что он работает правильно, в приведенном выше предупреждении компилятора приведено следующее:

return ((item - (my->items))/(my->itemSize));

'item' - это 'void *'; 'my-> items' - это 'void *'; 'my-> itemSize' является 'int'

При преобразовании 'item' и 'my-> items' в качестве 'int *' программа работала некорректно. Каков наилучший способ удалить предупреждение?

Ответы [ 4 ]

16 голосов
/ 26 апреля 2010

сложения и вычитания с указателями работают с размером заостренного типа:

int* foo = 0x1000;
foo++;
// foo is now 0x1004 because sizeof(int) is 4

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

Однако по нескольким причинам sizeof(void) возвращает 1, и арифметика работает так, как если бы это был указатель char. Поскольку это семантически неверно, вы получите предупреждение.

Для подавления предупреждения используйте char указатели.

3 голосов
/ 26 апреля 2010

В ролях char *:

return ((char *)item - (char *)my->items)/my->itemSize);

Так как char имеет размер 1 байт, вы получите ожидаемое значение по сравнению с вашим примером указателя int *, который вычисляет, сколько int s между двумя адресами. Вот как работает арифметика указателей.

0 голосов
/ 26 апреля 2010

Если вы пытаетесь выполнить обычную арифметику, вы должны разыменовать указатель (например, *item). Если вы пытаетесь выполнить арифметику с указателями, указатель должен иметь тип, например char* или int* (в противном случае компилятор не будет знать, на сколько увеличить).

0 голосов
/ 26 апреля 2010

Проблема в том, что вы выполняете арифметические операции с указателем, интересно, как это работает правильно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...