问题描述
当一个指向特定类型(比如 int
, char
, float
, ..)的指针增加时,它的值增加该数据类型的大小.如果指向x
大小数据的void
指针递增,它如何指向x
字节前面?编译器如何知道将 x
添加到指针的值?
When a pointer to a particular type (say int
, char
, float
, ..) is incremented, its value is increased by the size of that data type. If a void
pointer which points to data of size x
is incremented, how does it get to point x
bytes ahead? How does the compiler know to add x
to value of the pointer?
推荐答案
最终结论:void*
上的算术在 C 和 C++ 中都是非法.
Final conclusion: arithmetic on a void*
is illegal in both C and C++.
GCC 允许它作为扩展,参见 算术上void
- 和函数指针(注意本节是手册C 扩展"一章的一部分).为了与 GCC 兼容,Clang 和 ICC 可能允许 void*
算术.其他编译器(例如 MSVC)不允许对 void*
进行算术运算,如果指定了 -pedantic-errors
标志,或者 -Werror-指定了指针算术
标志(如果您的代码库也必须使用 MSVC 编译,则此标志很有用).
GCC allows it as an extension, see Arithmetic on void
- and Function-Pointers (note that this section is part of the "C Extensions" chapter of the manual). Clang and ICC likely allow void*
arithmetic for the purposes of compatibility with GCC. Other compilers (such as MSVC) disallow arithmetic on void*
, and GCC disallows it if the -pedantic-errors
flag is specified, or if the -Werror-pointer-arith
flag is specified (this flag is useful if your code base must also compile with MSVC).
引自 n1256 草案.
Quotes are taken from the n1256 draft.
标准对加法操作的说明:
The standard's description of the addition operation states:
6.5.6-2:对于加法,两者之一操作数应具有算术类型,或者一个操作数应该是一个指向一个对象类型,另一个应有整数类型.
因此,这里的问题是 void*
是否是指向对象类型"的指针,或者等价地,void
是否是对象类型".对象类型"的定义是:
So, the question here is whether void*
is a pointer to an "object type", or equivalently, whether void
is an "object type". The definition for "object type" is:
6.2.5.1:类型被划分为对象类型(完全描述对象的类型)、函数类型(描述函数的类型)和不完全类型(描述对象但缺乏确定其大小所需信息的类型).
标准将void
定义为:
6.2.5-19:void
类型包括一组空值;它是一个不完整的类型,不能完成.
由于 void
是一个不完整的类型,所以它不是一个对象类型.因此它不是加法运算的有效操作数.
Since void
is an incomplete type, it is not an object type. Therefore it is not a valid operand to an addition operation.
因此您不能对 void
指针执行指针运算.
Therefore you cannot perform pointer arithmetic on a void
pointer.
最初,由于 C 标准的这些部分,人们认为 void*
算术是允许的:
Originally, it was thought that void*
arithmetic was permitted, because of these sections of the C standard:
6.2.5-27:指向 void 的指针应具有相同的表示和对齐要求作为指向 a 的指针字符类型.
然而,
相同的表示和对齐要求意味着可互换性作为论据函数,返回值来自职能部门和工会成员.
所以这意味着 printf("%s", x)
具有相同的含义,无论 x
的类型是 char*
还是 void*
,但这并不意味着您可以对 void*
进行算术运算.
So this means that printf("%s", x)
has the same meaning whether x
has type char*
or void*
, but it does not mean that you can do arithmetic on a void*
.
这篇关于C中void指针的指针算法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!