C中void指针的指针算法 [英] Pointer arithmetic for void pointer in C

查看:25
本文介绍了C中void指针的指针算法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当一个指向特定类型(比如 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:对于加法,两者之一操作数应具有算术类型,或者一个操作数应该是一个指向一个对象类型,另一个应有整数类型.

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 是否是对象类型".对象类型"的定义是:

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:类型被划分为对象类型(完全描述对象的类型)、函数类型(描述函数的类型)和不完全类型(描述对象但缺乏确定其大小所需信息的类型).

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:void 类型包括一组空值;它是一个不完整的类型,不能完成.

6.2.5-19: The void type comprises an empty set of values; it is an incomplete type that cannot be completed.

由于 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 的指针字符类型.

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* 进行算术运算.

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指针的指针算法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆