错误:ANSI C++禁止在赋值中从"void *"进行隐式转换

error: ANSI C++ forbids implicit conversion from `void *' in assignment

本文关键字:void 转换 C++ ANSI 禁止 赋值 错误      更新时间:2023-10-16

我收到这个错误消息,但我似乎不明白。ANSI C++禁止从赋值中的"void*"进行隐式转换是什么意思。Fork函数只取函数名和一个数字

线程::Fork(VoidFunctionPtr函数,int arg)

错误消息:

../threads/threadtest.cc: In function `void ServerThread(int)':
../threads/threadtest.cc:72: ANSI C++ forbids implicit conversion from `void *' in assignment
../threads/threadtest.cc:78: implicit declaration of function `int WorkerThread(...)'

区域:

72-78:

  nextReq = list -> Remove();

  //check till the end                                                                     
  while (nextReq != NULL)
    {
      WorkerThread(&nextReq);

代码:

#include "copyright.h"
#include "system.h"
#include <stdio.h>
#include "request.h"
extern void serve(char *url);
//GLOBAL VARIABLE LIST
List *list;
//----------------------------------------------------------------------
// ThreadTest
//  read file and serve urls
//----------------------------------------------------------------------
void 
ClientThread(int request)
{
  const int sz = 50;
  char url[sz];
  FILE *fp = fopen("url.txt", "r");
  if (!fp)
    printf("  Cannot open file url.txt!n");
  else {
    int pos = 0;
    char c = getc(fp);
    while (c != EOF || pos == sz - 1) {
      if (c == 'n') {
    url[pos] = '';
    serve(url);
    pos = 0;
    //Store necessary information in a Request object for each request. 
    Request req(url, request, 1);
    Request *reqq = &req; //req points to the object
    list->Append(reqq);
      }
      else {
    url[pos++] = c;
      }
      c = getc(fp);
    }
    fclose(fp);
  }
}
//----------------------------------------------------------------------
void
ServerThread(int which)
{
  Request *nextReq;
  //gets the first node off the list
  nextReq = list -> Remove();

  //check till the end
  while (nextReq != NULL)
    {
      WorkerThread(nextReq);
    }

}
//----------------------------------------------------------------------
void
WorkerThread (Request req)
{
  serve(req.url);
  currentThread -> Yield();
}
//----------------------------------------------------------------------
void
ThreadTest()
{
    DEBUG('t', "Entering SimpleTest");
    printf("THREAD TEST");
    //Thread *c = new Thread("client thread");
    Thread *s = new Thread("server thread");
    s->Fork(ServerThread, 1);
    ClientThread(0);
}

这似乎是有问题的行之一:

nextReq = list -> Remove();

看起来list->Remove()返回一个void *。C++需要强制转换才能将其转换为另一个指针(C不需要)。所以将其更改为:

nextReq = static_cast<Request *>(list -> Remove());

(或者,考虑将List作为模板类,这样就可以避免这些不安全的强制转换。根据您的代码,STL类std::queue<Request>应该满足您的需求。)

第二个有问题的行是在定义WorkerThread()之前对它的调用。在定义ServerThread()之前,您需要为函数添加一个原型。否则,编译器不知道它的原型是什么,一旦达到ServerThread()的真正定义,它就应该抱怨它与之前推导的原型不匹配。

void WorkerThread(Request);
void
ServerThread(int which)
{
    // ...

(或者,由于WorkerThread()不调用ServerThread(),您可以交换这两个函数的定义顺序来解决问题。)


此外,请注意此代码是错误的:

Request req(url, request, 1);
Request *reqq = &req; //req points to the object
list->Append(reqq);

构造一个对象,然后将指向堆栈分配对象的指针推送到列表中。当ClientThread()返回时,此对象将被销毁,并且您将留下一个指向不再存在的对象的指针。使用此指针将触发未定义的行为。请考虑使用Request *reqq = new Request(url, request, 1);在堆上分配一个新的Request(但不要忘记在处理对象后将其delete)。

或者,更好的是,使用std::queue<Request>,正如我之前建议的那样——然后您可以只使用queue.emplace(url, request, 1);。但请注意,您确实需要一种方法来同步多个线程对队列的访问。