многопоточность — ошибка: ANSI C ++ запрещает неявное преобразование из `void * ‘в присваивании

Я получаю это сообщение об ошибке, и я, кажется, не понимаю его.
Что это означает, что 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);

}

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 в кучу с помощью Request *reqq = new Request(url, request, 1); (но не забудьте delete объект после обработки).

Или, еще лучше, используйте std::queue<Request> как я предлагал ранее — тогда вы можете просто queue.emplace(url, request, 1);, Но учтите, что вам нужен способ синхронизации доступа к очереди из нескольких потоков.

2

Другие решения


По вопросам рекламы [email protected]