Подтвердить что ты не робот

Void * арифметика

#include<stdio.h>
int main(int argc,char *argv[])
{
   int i=10;
   void *k;
   k=&i;

   k++;
   printf("%p\n%p\n",&i,k);
   return 0;
}

Является ли ++ законной операцией на void *? Некоторые книги говорят, что это не но K и R ничего не говорят о void * арифметике (стр. 93, 103, 120, 199 K & R 2/e)

Просьба пояснить.

PS: GCC не жалуется, по крайней мере, в k ++.

4b9b3361

Ответ 1

Это расширение

Чтобы это имело смысл, нам нужно рассмотреть массив void. Соответствующая информация для void - (§6.2.5/19)

Тип void содержит пустой набор значений; это неполный тип, который не может быть завершен.

Однако определение массива требует, чтобы тип элемента не был неполным (§6.2.5/20, сноска 36)

Так как типы объектов не включают неполные типы, не может быть создан массив неполного типа.

Следовательно, k+1 не может быть допустимым выражением.

Ответ 2

Нет, арифметика на void* не распространяется на стандарт. Используйте char* для этого.

Ответ 3

Вы не можете увеличить указатель до void. Компилятор не знает, что такое размер целевой структуры.

Ответ 4

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

Ответ 5

Арифметика на void * является расширением GCC. Когда я компилирую ваш код с помощью clang -Wpointer-arith, вывод будет следующим:

test.c:9:4: warning: use of GNU void* extension [-Wpointer-arith]
k++;
~^

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


int *p;
char *p2;
p++; /* adds sizeof(int) to p */
p2 += 2; /* adds 2 * sizeof(char) to p2 */

Так как void не имеет размера, вы не сможете выполнять арифметику указателя на указателях void*, но GNU C позволяет это.