努力理解空指针 [英] Towards understanding void pointers

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

问题描述

在我的答案中,我提到取消引用void指针是一个坏主意.但是,当我这样做时会发生什么?

In my answer I mention that dereferencing a void pointer is a bad idea. However, what happens when I do this?

#include <stdlib.h>
int main (void) {
 void* c = malloc(4);
 *c;
 &c[0];
}

编译:

gcc prog.c -Wall -Wextra
prog.c: In function 'main':
prog.c:4:2: warning: dereferencing 'void *' pointer
  *c;
  ^~
prog.c:5:4: warning: dereferencing 'void *' pointer
  &c[0];
    ^
prog.c:5:2: warning: statement with no effect [-Wunused-value]
  &c[0];
  ^

这是来自Wandbox的图片,供那些认为没有发生的人

Here is an image from Wandbox for those who say it didn't happen:

和Ideone中的实时演示.

它实际上会尝试读取c指向的内存,然后获取该结果,但是实际上什么都不做?否则此行将完全无效(但GCC不会发出警告).

It will actually try to read what the memory that c points to has, and then fetch that result, but actually do nothing in the end? Or this line will simply have no effect (but then GCC wouldn't produce a warning).

我在想,由于编译器对数据类型一无所知,因此如果不知道类型的大小,它将无法做很多事情.

I am thinking that since the compiler doesn't know anything about the data type, it won't be able to do much, without knowing the size of the type.

为什么取消引用void*不会产生错误,而只是警告?

Why derefencing a void* does not produce an error, but just a warning?

如果我尝试分配作业,将会收到错误消息:

If I try an assignment, I will get an error:

无效使用void表达式

invalid use of void expression

但是单独引用不应该产生错误吗?

but shouldn't the dereferencing alone produce an error?

推荐答案

来自C11 6.3.2.3"void":

From C11 6.3.2.3 "void":

不得以任何方式使用void表达式(具有void类型的表达式)的(不存在)值,并且不得将隐式或显式转换(除void外)应用于此类表达式.如果将任何其他类型的表达式评估为void表达式,则将其值或指示符丢弃. (将评估void表达式的副作用.)

The (nonexistent) value of a void expression (an expression that has type void) shall not be used in any way, and implicit or explicit conversions (except to void) shall not be applied to such an expression. If an expression of any other type is evaluated as a void expression, its value or designator is discarded. (A void expression is evaluated for its side effects.)

因此,表达式可以具有void类型,您不能对该表达式的结果做任何事情(例如将其分配给某物). *c是不执行任何操作的有效表达式.

So an expression can have void type, you just can't do anything with the result of that expression (such as assign it to something). *c is a valid expression that does nothing.

6.2.5/19类型"

6.2.5/19 "Types"

void类型包含一组空值;这是一种不完整的对象类型,无法完成.

The void type comprises an empty set of values; it is an incomplete object type that cannot be completed.

6.5.6/2加法运算符"

6.5.6/2 "Additive operators"

另外,两个操作数都应具有算术类型,或者一个操作数应是指向完整对象类型的指针,另一个操作数应具有整数类型.

For addition, either both operands shall have arithmetic type, or one operand shall be a pointer to a complete object type and the other shall have integer type.

数组下标是根据指针算术定义的.因此,通常不允许使用表达式&c[0].

And array subscripting is defined in terms of pointer arithmetic. So normally, the expression &c[0] would not be allowed.

GCC允许对void类型(并因此将其下标为数组)的指针算术作为扩展.

GCC allows pointer arithmetic on (and therefore subscripting arrays of) void types as an extension.

这篇关于努力理解空指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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