在实际已经转换时取消引用void指针错误

时间:2022-08-01 19:52:48

Situation

Consider the following source code which aims to print two a's, i.e. 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. My hunch is based off the fact that the first variable works just fine.

虽然b_pnt确实被声明为一个void指针,但它在第7行的定义中被转换为一个字符指针。我唯一猜测为什么它的抱怨与我在同一时间引用时只能进行转换的事实有关。我的预感是基于第一个变量工作正常的事实。

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. It could indeed have been avoided entirely ofcourse with the correct pointer type.

我故意用void指针开始说明问题。确实可以完全避免使用正确的指针类型。

1 个解决方案

#1


1  

Just because you performed a cast when assigning to b_pnt doesn't mean that it's type changed. It's type is still void * and dereferencing it is an error.

仅仅因为你在分配给b_pnt时执行了强制转换并不意味着它的类型发生了变化。它的类型仍然无效*并且取消引用它是一个错误。

You can freely assign any non-function pointer type to a void * without a warning. 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 *。但是编译器没有跟踪存储在那里的指针类型,因此它仍然是一个无效的*需要在被解除引用之前进行转换。

#1


1  

Just because you performed a cast when assigning to b_pnt doesn't mean that it's type changed. It's type is still void * and dereferencing it is an error.

仅仅因为你在分配给b_pnt时执行了强制转换并不意味着它的类型发生了变化。它的类型仍然无效*并且取消引用它是一个错误。

You can freely assign any non-function pointer type to a void * without a warning. 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 *。但是编译器没有跟踪存储在那里的指针类型,因此它仍然是一个无效的*需要在被解除引用之前进行转换。