当指向特定类型(例如 int
、char
、float
等)的指针递增时,其值会增加该数据类型的大小。如果指向大小为 x 的数据的 void 指针递增,它如何指向前面 x 字节?编译器如何知道将 x
添加到指针的值?
最佳答案
最终结论:关于 void*
的算术在 C 和 C++ 中都是非法。
GCC 允许将其作为扩展,请参阅 Arithmetic on void
- and Function-Pointers (请注意,本节是手册“C 扩展”一章的一部分)。 Clang 和 ICC 可能允许 void*
算术以与 GCC 兼容。其他编译器(例如 MSVC)不允许对 void*
进行算术运算,并且如果 -pedantic-errors
则 GCC 不允许它指定了标志,或者如果 -Werror=pointer-arith
指定标志(如果您的代码库还必须使用 MSVC 编译,则此标志很有用)。
C 标准说话
引文取自 n1256 草案。
标准对加法运算的描述如下:
6.5.6-2: For addition, either both operands shall have arithmetic type, or one operand shall be a pointer to an object type and the other shall have integer type.
所以,这里的问题是 void*
是否是一个指向“对象类型”的指针,或者等效地,是否 void
是一种“对象类型”。 “对象类型”的定义是:
6.2.5.1: Types are partitioned into object types (types that fully describe objects) , function types (types that describe functions), and incomplete types (types that describe objects but lack information needed to determine their sizes).
该标准定义了void
如:
6.2.5-19: The
void
type comprises an empty set of values; it is an incomplete type that cannot be completed.
自 void
是不完整类型,它不是对象类型。因此它不是加法运算的有效操作数。
因此您无法对 void
执行指针算术指针。
注释
最初,人们认为void*
由于 C 标准的这些部分,算术是允许的:
6.2.5-27: A pointer to void shall have the same representation and alignment requirements as a pointer to a character type.
但是,
The same representation and alignment requirements are meant to imply interchangeability as arguments to functions, return values from functions, and members of unions.
所以这意味着printf("%s", x)
x
是否具有相同的含义类型为char*
或void*
,但这并不意味着您可以对 void*
进行算术运算.
关于c - C中void指针的指针运算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58446185/