我可以在 C 中对 void * 指针进行算术运算吗?

发布于 2024-09-29 00:52:07 字数 533 浏览 7 评论 0原文

这是有效的

void *p = &X; /* some thing */
p += 12;

吗?如果有效的话,p 现在指向什么? 我有(第三方)代码可以执行此操作(并且可以干净地编译),我的猜测是 void * 被视为 char *。我值得信赖的 K&R 在这个主题上保持沉默

编辑:我的小测试应用程序在 gcc 4.1.1 上运行良好,并将 void * 视为 char *。但是 g++ barfs

我知道如何正确地做到这一点。我需要知道是否必须清理此代码库才能找到其完成的所有位置。

BTW gcc -pedantic 抛出警告

摘要:

C 规范不明确。它说,就表示形式和用作函数参数而言,void*=char*。但对于指针算术却保持沉默。

  • gcc (4) 允许它并将其视为 char *
  • g++ 拒绝它
  • gcc -pedantic 警告它
  • vs2010 c 和 c++ 拒绝它

is this valid

void *p = &X; /* some thing */
p += 12;

and if so what does p now point to?
I have (third party) code that does this (and compiles cleanly) and my guess is that the void * was treated as a char *. My trusty K&R is silent(ish) on the topic

EDIT: My little test app runs fine on gcc 4.1.1 and treats void * as char *. But g++ barfs

I know how to do it properly. I need to know if I have to clean this code base to find all the places its done.

BTW gcc -pedantic throws up a warning

Summary:

The C spec is ambiguous. It says that in terms of representation and use as function parameters void* =char*. But it is silent regarding pointer arithmetic.

  • gcc (4) permits it and treats it as
    char *
  • g++ refuses it
  • gcc -pedantic warns about it
  • vs2010 both c and c++
    refuses it

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

時窥 2024-10-06 00:52:07

不,这是不合法的。 void* 不能任意递增。它需要首先转换为特定类型。

如果您想将其增加特定的字节数,那么这就是我使用的解决方案。

p = ((char*)p) + 12;

char 类型很方便,因为它的定义大小为 1 个字节。

编辑

有趣的是它在 gcc 上运行并带有警告。我在 Visual Studio 2010 上进行了测试并验证它无法编译。我对标准的有限理解会说 gcc 在这里出错。您可以添加以下编译标志吗

-Wall -ansi -pedantic

No this is not legal. A void* cannot be arbitrarily incremented. It needs to be cast to a specific type first.

If you want to increment it by a specific number of bytes then this is the solution I use.

p = ((char*)p) + 12;

The char type is convenient because it has a defined size of 1 byte.

EDIT

It's interesting that it runs on gcc with a warning. I tested on Visual Studio 2010 and verified it does not compile. My limited understanding of the standard would say that gcc in the error here. Can you add the following compilation flags

-Wall -ansi -pedantic
美煞众生 2024-10-06 00:52:07

引用规范:

§6.5.6/2:对于加法,两个操作数都应具有算术类型,或者一个操作数应是指向对象类型的指针,另一个操作数应具有整数类型。 (递增相当于加1。)

指向 void 的指针不是指向对象类型的指针,根据以下摘录:

§6.2.5/1:[...]类型
分为对象类型(完全描述对象的类型)、函数类型(类型
描述函数)和不完整类型(描述对象但缺乏
确定其大小所需的信息)。

§6.2.5/19:void 类型包含一组空值;这是一个不完整的类型,不能
已完成。

因此,对于指向 void 类型的指针未定义指针算术。

To quote from the spec:

§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. (Incrementing is equivalent to adding 1.)

A pointer to void is not a pointer to an object type, as per these excerpts:

§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).

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

Therefore, pointer arithmetic is not defined for pointer to void types.

夜灵血窟げ 2024-10-06 00:52:07

这取决于编译器。那些允许它的人将 sizeof(*(void *)) 视为 1。

编辑:它仅适用于 void 指针算术。在这种情况下,使用 sizeof(int) 或 0 的步长是没有意义的。使用它的人的共同期望是尽可能最小的步长。

It depends on compiler. Those that allow it consider sizeof(*(void *)) as 1.

EDIT: it's only for void pointer arithmetic. It would have no sense using in this case steps of sizeof(int) or of 0. The common expectations of someone who uses it would be the smallest possible step.

巨坚强 2024-10-06 00:52:07

你的猜测是正确的。

在标准 ISO C99 的第 6.2.5 节第 26 段中,它声明 void 指针和字符指针将具有相同的表示和对齐要求(释义)。

Your guess is correct.

In the standard ISO C99, section 6.2.5 paragraph 26, it declares that void pointers and character pointers will have the same representation and alignment requirements (paraphrasing).

不必了 2024-10-06 00:52:07

您可能想查看此问题的最高投票答案

指针算术C 中的空指针

You may want to have a look at the top voted answer for this question

Pointer arithmetic for void pointer in C

油焖大侠 2024-10-06 00:52:07

我认为你不能,因为它不知道它的类型,因此无法寻求正确的字节数。

首先将其转换为类型,即(int)

I don't think you can, because it doesn't know its type, therefore can not seek the correct amount of bytes.

Cast it to a type first, i.e. (int).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文