简体   繁体   English

当 infact 已经转换时取消引用 void 指针错误

[英]De-Referencing void pointer error when infact already cast

Situation情况

Consider the following source code which aims to print two a's, ie output should be "aa":考虑以下旨在打印两个 a 的源代码,即输出应为“aa”:

#include <stdio.h>

int main ()
{
char a = 'a';
void* a_pnt = &a;
void* b_pnt = (char*)a_pnt;

printf("%c", *(char*)a_pnt);
printf("%c", *b_pnt);// why is the compiler saying I am dereferencing a void pointer? It was already cast
return 0;
}

Complication并发症

The printing of the first "a" works but the compiler is giving a compile time error on line 10 (second printing of "a") saying:第一个“a”的打印有效,但编译器在第 10 行(“a”的第二次打印)给出了一个编译时错误说:

Invalid use of void expression void 表达式的无效使用

and a warning on the same line saying:并在同一行警告说:

Dereferencing 'void *' pointer取消引用“void *”指针

Although b_pnt was indeed declared a void pointer, it was cast to a character pointer in its definition on line 7. My only guess as to why its complaining is something to do with the fact that I can only cast when referencing at the same time.尽管 b_pnt 确实被声明为空指针,但它在第 7 行的定义中被强制转换为字符指针。我唯一的猜测是为什么它会抱怨,因为我只能在同时引用时进行强制转换。 My hunch is based off the fact that the first variable works just fine.我的预感是基于第一个变量工作正常的事实。

Solution解决方案

The solution is declare and define a character variable called 'b' and cast to character pointer upfront before printing it:解决方案是声明并定义一个名为 'b' 的字符变量,并在打印之前预先转换为字符指针:

#include <stdio.h>

int main ()
{
char a = 'a';
void* a_pnt = &a;
void* b_pnt = a_pnt;
char b = *((char*)b_pnt);

printf("%c", *(char*)a_pnt);
printf("%c", b);// why is the compiler saying I am dereferencing a pointer?
return 0;
}

The question still remains: Why did the initial attempt fail?问题仍然存在:为什么最初的尝试失败了?

I am deliberately starting off with void pointer to illustrate the issue.我故意从 void 指针开始来说明这个问题。 It could indeed have been avoided entirely ofcourse with the correct pointer type.当然,使用正确的指针类型确实可以完全避免这种情况。

Just because you performed a cast when assigning to b_pnt doesn't mean that it's type changed.仅仅因为您在分配给b_pnt时执行了b_pnt并不意味着它的类型已更改。 It's type is still void * and dereferencing it is an error.它的类型仍然是void *并且取消引用它是一个错误。

You can freely assign any non-function pointer type to a void * without a warning.您可以自由地将任何非函数指针类型分配给void *而不会发出警告。 But the compiler doesn't keep track of what kind of pointer was stored there, so it's still a void * that needs to be casted before it can be dereferenced.但是编译器不会跟踪存储在那里的指针类型,因此它仍然是一个需要强制转换的void *才能取消引用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM