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

时间:2014-09-26 03:12:44

标签: c++ multithreading operating-system nachos

我收到此错误消息,我似乎并不理解。 ANSI C ++是什么意思禁止从`void *'隐式转换在任职? 。而Fork函数只接受函数名称和数字

Thread :: Fork(VoidFunctionPtr func,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(...)'

REGION:

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] = '\0';
    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);

}

1 个答案:

答案 0 :(得分:2)

这似乎是违规行之一:

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在堆上分配新的Request *reqq = new Request(url, request, 1);(但在处理完对象后不要忘记delete)。

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