void *算术
#include 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 *算术的内容(K&R 2 / e的第93,103,120,199页)
请澄清。
PS:GCC至少在k ++中没有抱怨。
这是GCC的延伸 。
在GNU C中,指向void的指针和指向函数的指针都支持加法和减法操作。 这是通过将
void
或函数的大小视为1来完成的。
如果添加-pedantic
标志,它将产生警告:
warning: wrong type argument to increment
如果您想遵守标准,请将指针强制转换为char*
:
k = 1 + (char*)k;
该标准指定无法对void*
执行加法( k+1
),因为:
-
指针运算是通过将
k
作为指向void
数组的第一个元素(#0)的指针(C99§6.5.6/ 7)来完成的,而k+1
将返回该“数组”中的元素#1(§6.5) 0.6 / 8)。 -
为此,我们需要考虑一个
void
数组。void
的相关信息是(§6.2.5/ 19)void
类型包含一组空值; 它是一种不完整的类型,无法完成。 -
但是,数组的定义要求元素类型不能不完整(§6.2.5/ 20,脚注36)
由于对象类型不包含不完整类型, 因此无法构造不完整类型的数组。
因此k+1
不能是有效的表达式。
不,标准不涵盖void*
算术void*
。 为此使用char*
。
您不能将指针增加到void
。 编译器不知道sizeof目标结构是什么。
该标准要求所有指针算术运算符都要求指针指向完整的对象类型。 void
是一种不完整的类型。 海湾合作委员会做错了。
void *上的算术是GCC扩展。 当我使用clang -Wpointer-arith
编译代码时,输出为:
test.c:9:4:警告:使用GNU void * extension [-Wpointer-arith] ķ++; 〜^
指针增量的通常行为是将指针类型的大小添加到指针值。 例如 :
int *p; char *p2; p++; /* adds sizeof(int) to p */ p2 += 2; /* adds 2 * sizeof(char) to p2 */
由于void
没有大小,你不应该对void*
指针执行指针运算,但GNU C允许它。