【问题标题】:error: ANSI C++ forbids implicit conversion from `void *' in assignment错误:ANSI C++ 禁止在赋值中从“void *”进行隐式转换
【发布时间】:2014-11-20 23:41:55
【问题描述】:

我收到此错误消息,但我似乎不明白。 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(...)'

地区:

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);

}

【问题讨论】:

  • 这肯定不是你能管理的最好的MCVE

标签: c++ multithreading operating-system nachos


【解决方案1】:

这似乎是违规行之一:

nextReq = list -> Remove();

list-&gt;Remove() 似乎返回了 void *。 C++ 需要一个强制转换来把它变成另一个指针(C 不需要)。所以把它改成:

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

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

第二个违规行是您在定义之前对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&lt;Request&gt;——然后你可以只使用queue.emplace(url, request, 1);。但请注意,您确实需要一种方法来同步从多个线程访问队列。

【讨论】:

  • 在函数'void ServerThread(int):我得到这个错误:从Request **' to non-scalar type Request'转换。 WorkerThread(&nextReq);
  • @monkeydoodle 你需要改用WorkerThread(*nextReq);WorkerThread() 接受 Request,而不是任何类型的指针。
猜你喜欢
  • 1970-01-01
  • 2017-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-21
  • 1970-01-01
  • 1970-01-01
  • 2021-11-08
相关资源
最近更新 更多