为什么在将值打印到地址位于指针中的内存中之前,必须将void指针强制转换为int或其他内容? [英] Why do we have to cast a void pointer to int or something else before printing the value in the memory whose address is in the pointer?

查看:126
本文介绍了为什么在将值打印到地址位于指针中的内存中之前,必须将void指针强制转换为int或其他内容?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道为什么在打印内存中的地址内容之前,必须将void指针强制转换为int *char *,即使我们告诉printf()函数如何解释其中的数据也是如此.记忆吗?

假设我们有以下代码:

int main (void)
{
 void* c = malloc(4);
 printf("%d",*c);
 return 0;
}

为什么无法做到这一点?

因此,我想问清楚的是,这种不可能的原因是什么?

经过所有的答案和研究,我仍然不确定在汇编中致命错误的确切位置.我感到困惑的主要原因是,我的编译器(gcc)仅在提示取消引用空指针"时给出警告.这是实际错误吗?据我所知,即使有警告,程序仍应编译.

EDIT2 我仍然对ERROR和WARNING看起来完全独立但由同一段代码生成的原因感到困惑:

pointer.c:7:13: warning: dereferencing 'void *' pointer                                                                                                                                                           
 printf("%d",*p);                                                                                                                                                                                                 
             ^~                                                                                                                                                                                                   
pointer.c:7:13: error: invalid use of void expression                                                                                                                                                             
 printf("%d",*p);

某些用户说,仅当我们尝试使用取消折旧的结果时才会出现该错误,而警告是当我们实际为VOID指针分配内存时.

显然不是这种情况,因为如果我们删除printf行,我们的确只会收到警告,但会得到一个完全无关的提示.

pointer.c:6:8: warning: unused variable 'p' [-Wunused-variable]                                                                                                                                                   
 void * p=malloc(4);    

解决方案

问题不在于printf()的解释,而在于取消引用.

对于类似这样的语句

 printf("%d",*c);

您正试图取消引用void *.现在,void是永远不完整的类型.您不能取消引用指向未完成的事物"的指针,并因此获得有意义的结果.

引用C11,第§6.2.5章,P19

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

换句话说(尽管有点麻烦),C是一种强类型语言,对于每种定义的类型,编译器都知道(或必须知道)多少个字节(大小)从内存中读取/读取/操作.对于void类型,编译器是笨拙的.

出于同样的原因,void *上也不允许使用指针算术. gcc具有与char *相同的 treat a void*扩展名,但这是扩展名,而不是标准扩展名.


我的编译器针对以下语句产生错误: 在线检查 .

I wonder why is it necessary to cast a void pointer to an int * or char * before printing the contents of the address in memory, even though we tell the printf() function how to interpret the data in memory?

Let's say that we have the following code:

int main (void)
{
 void* c = malloc(4);
 printf("%d",*c);
 return 0;
}

Why it is not possible to do this?

So to be clear my question is what is the reason for this being not possible?

EDIT: After all the answers and research I am still not convinced exactly where the fatal error in the compilation is. The main reason I am confused is that my compiler (gcc) only gives a WARNING when telling about "dereferencing a void pointer". Is this the actual error? From what I know the program should still compile even with warnings.

EDIT2 I am still confused about the reasons for which we have an ERROR and a WARNING that appear to be completely separate but are generated by the same piece of code:

pointer.c:7:13: warning: dereferencing 'void *' pointer                                                                                                                                                           
 printf("%d",*p);                                                                                                                                                                                                 
             ^~                                                                                                                                                                                                   
pointer.c:7:13: error: invalid use of void expression                                                                                                                                                             
 printf("%d",*p);

Some users say that the error appears only when we try to use the result of the derefenciation and that the WARNING is when we actually alocate memory for the VOID pointer.

This is clearly NOT the case since if we remove the printf line we do indeed get only a warning but a COMPLETELY UNRELATED ONE.

pointer.c:6:8: warning: unused variable 'p' [-Wunused-variable]                                                                                                                                                   
 void * p=malloc(4);    

解决方案

The problem is not the interpretation of printf(), it's with the dereference.

In the case of a statement like

 printf("%d",*c);

you are attempting to dereference a void *. Now, void is a forever-incomplete type. You cannot dereference a pointer to "something incomplete" and get something meaningful as a result.

Quoting C11, chapter §6.2.5 , P19

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

To put it in other words (though a bit of my own), C is a strongly typed language and for each defined type, the compiler knows (or, must know) how many bytes (size) from memory it needs to read / operate on. For a void type, the compiler is clueless.

For the very same reason, pointer arithmetic is also not allowed on void *s. gcc has an extension which treats a void* the same as char *, but that's an extension, not standard.


EDIT:

My compiler produces an error for the statement, check online.

这篇关于为什么在将值打印到地址位于指针中的内存中之前,必须将void指针强制转换为int或其他内容?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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