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 ++.
Ответы
Ответ 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 позволяет это.