从“void*”转换为指向非“void”的指针需要显式转换(第 17 行)

Posted

技术标签:

【中文标题】从“void*”转换为指向非“void”的指针需要显式转换(第 17 行)【英文标题】:Conversion from 'void*' to pointer to non-'void' requires an explicit cast (Line 17) 【发布时间】:2012-07-13 17:45:45 【问题描述】:

我正在阅读《Learn C the Hard Way》一书,当我尝试运行该程序时,我收到以下错误消息:

从“void*”转换为指向非“void”的指针需要显式转换。

我不知道如何解决这个问题,我必须更改结构中的返回变量吗?

还是看一下,代码在这里:(在Visual C++ 2010上编译,还没试过GCC)。

   //learn c the hardway

  #include <assert.h>
  #include <stdlib.h>
  #include <string.h> 
  #include <stdio.h>

  struct Person 
      char *name;
      int age;
      int height;
      int weight; 
  ;

  struct Person *Person_create(char *name, int age, int height, int weight) 
  
      struct Person *who = malloc(sizeof(struct Person)); 
      assert(who != NULL);

      who->name = strdup(name);
      who->age = age; 
      who->height = height;
      who->weight = weight;

      return who;
   

  void Person_destroy(struct Person *who)
  
      assert(who != NULL);

      free(who->name);
      free(who);
  

  void Person_print(struct Person *who) 
  
      printf("Name: %s\n", who->name);
      printf("\tAge: %d\n", who->age); 
      printf("\tHeight: %d\n", who->height);
      printf("\tWeight: %d\n", who->weight); 
  

  int main(int argc, char *argv[])
  
      // make two people structures 
      struct Person *joe = Person_create(
              "Joe Alex", 32, 64, 140);

      struct Person *frank = Person_create(
              "Frank Blank", 20, 72, 180); 

      // print them out and where they are in memory 
      printf("Joe is at memory location %p:\n", joe);
      Person_print(joe);

      printf("Frank is at memory location %p:\n", frank);
      Person_print(frank); 

      // make everyone age 20 years and print them again 
      joe->age += 20;
      joe->height -= 2;
      joe->weight += 40; 
      Person_print(joe);

      frank->age += 20;
      frank->weight += 20; 
      Person_print(frank);

      // destroy them both so we clean up 
      Person_destroy(joe);
      Person_destroy(frank);

      return 0;
  

【问题讨论】:

如果你为 C 编译,它应该可以工作。但是在 C++ 中,强制转换是必要的。 (如果您选择 C++,您可能需要考虑使用更多类似 C++ 的功能。) 您将其编译为 C 还是 C++?语言不一样。 通过错误信息学习?这确实是“艰难的道路”。我相信有更好的方法。 @MrLister c.learncodethehardway.org/book/learn-c-the-hard-waych17.html 您似乎编写了一个 C 程序,然后尝试使用 C++ 编译器对其进行编译。不幸的是,在大多数情况下,这是一个荒谬的行为,就像您无法在 Java 编译器中编译您的 C 程序一样。尝试通过 C 编译器运行它,您可能会获得更好的运气。 【参考方案1】:

这行需要一个演员表:

  struct Person *who = malloc(sizeof(struct Person)); 

应该是:

  struct Person *who = (struct Person *)malloc(sizeof(struct Person)); 

这只是因为您将此代码编译为 C++,而不是 C。在 C 中,不需要转换,并且为您隐式完成。

【讨论】:

谢谢!我只是认为 MS C++ 只会为 C 编译,因为我使用 c 头文件。【参考方案2】:

Visual C++ 编译器将尝试根据正在编译的源文件的文件扩展名来确定正在编译的语言。例如,扩展名为 .cpp 的文件编译为 C++,扩展名为 .c 的文件编译为 C。

您的程序似乎是有效的 C,但不是有效的 C++:在 C 中,void*T* 的转换是隐式的;在 C++ 中需要强制转换。

如果您希望编译器将其编译为 C,您要么需要更改其文件扩展名,要么将 the /TC switch 传递给编译器,告诉编译器将文件编译为 C。

【讨论】:

【参考方案3】:
struct Person *who = malloc(sizeof(struct Person)); 

这需要在 C++ 中转换:

struct Person *who = (struct Person *) malloc(sizeof(struct Person)); 

在 C 中不需要强制转换,因为存在从 void * 到任何对象指针类型的隐式转换。这种隐式转换在 C++ 中不存在,因此在 C++ 中需要强制转换。

【讨论】:

【参考方案4】:

错误消息是由于 C 不需要显式转换,而 C++ 需要。尝试确保编译器将源代码视为 C 而不是 C++。

【讨论】:

以上是关于从“void*”转换为指向非“void”的指针需要显式转换(第 17 行)的主要内容,如果未能解决你的问题,请参考以下文章

将 void 指针转换为指向类型的指针时使用的术语是啥?

从void指针中获取一个指向short的int

如何在 CFFI 中找到指向结构的指针的地址并将其转换为 void**

访问从 void 指针转换的结构中的 char 指针

有没有办法避免隐式转换为 void*?

void指针意义Constvolatile#definetypedef接续符