return 值所需的无效函数?

Void function required to return value?

我写了一个用于创建pthread的函数如下:

void *downloadfile(void *arg)
{
  char *req_path = NULL;
  char local_path[PATH_BUFFER_SIZE];
  int returncode = 0;
  gfcrequest_t *gfr = NULL;
  FILE *file = NULL;
  int i = 0;
  
  /* Build your queue of requests here */
  for (i = 0; i < nrequests; i++) {
    // pthread mutex locking
    // doing something
    // pthread mutex unlocking

    localPath(req_path, local_path);

    file = openFile(local_path);

    gfr = gfc_create();
    gfc_set_server(&gfr, server);
    gfc_set_path(&gfr, req_path);
    gfc_set_port(&gfr, port);
    gfc_set_writefunc(&gfr, writecb);
    gfc_set_writearg(&gfr, file);

    fprintf(stdout, "Requesting %s%s\n", server, req_path);

    if (0 > (returncode = gfc_perform(&gfr))) {
      fprintf(stdout, "gfc_perform returned an error %d\n", returncode);
      fclose(file);
      if (0 > unlink(local_path))
        fprintf(stderr, "warning: unlink failed on %s\n", local_path);
    } else {
      fclose(file);
    }

    if (gfc_get_status(&gfr) != GF_OK) {
      if (0 > unlink(local_path))
        fprintf(stderr, "warning: unlink failed on %s\n", local_path);
    }

    fprintf(stdout, "Status: %s\n", gfc_strstatus(gfc_get_status(&gfr)));
    fprintf(stdout, "Received %zu of %zu bytes\n", gfc_get_bytesreceived(&gfr),
            gfc_get_filelen(&gfr));

    gfc_cleanup(&gfr);
    req_path = NULL;
  }
//  return 0;
}

我注释掉了“return 0;”声明,因为这是一个空函数,因此不应该 return 任何值。但是编译器抱怨

error: control reaches end of non-void function

如果我取消注释“return 0;”语句,错误消失。我很困惑。编译器如何要求 return 值的 void 函数?有人可以帮忙吗?

根据您的描述,我假设您的函数 downloadfile 将用作 pthread_create 调用中的 function-pointer 参数。

所以你有一个基本的误解。用于 pthread_create 的函数指针是 而不是 指向“无效函数”的函数指针。它是指向函数的函数指针,return 是一个空指针。 (顺便说一句:如果需要,您可以使用 pthread_join 函数获取 return 值)

所以换句话说:你的函数必须return一个void-pointer。如果您对 return 没有任何意义,只需使用 return NULL;

额外的细节:

https://man7.org/linux/man-pages/man3/pthread_create.3.html 我们有:

   int pthread_create(pthread_t *restrict thread,
                      const pthread_attr_t *restrict attr,
                      void *(*start_routine)(void *),
                      void *restrict arg);

这里有趣的部分是void *(*start_routine)(void *),意思是:

 void *(*start_routine)(void *)
 \----/\--------------/\------/
    |   Function ptr       |
    |   to a function   /----------\   
    |        that takes void pointer as argument
    |   and returns
/----------\
void pointer 

所以再次 - 要为 pthread_create 使用正确的函数指针参数,您需要一个 return 是 void-pointer.

的函数

because this is a void function

不,不是。它是 returning a void* 的函数。 Pthreads 使用签名void* f (void*) 的函数。根据 pthread 库设计,这是您唯一可以使用的函数。你不能选择其他任何东西。

error: control reaches end of non-void function

这是一个很好的错误,因为没有 return 语句的代码包含未定义的行为。具体来说 C17 6.9.1/12 说:

If the } that terminates a function is reached, and the value of the function call is used by the caller, the behavior is undefined.

例如,如果您没有使用 return 并且调用者检查结果 - 这将在 pthreads 库中发生,那么任何事情都可能发生。这是一个错误。

如果您对return函数中的任何内容不感兴趣,您必须 return NULL; 或等效的return 0;

值得注意的是,returning voidvoid* 之间的区别是 C 基础知识——这是你应该在进入 [=35 之前更早学习的东西=],这是一个更高级的话题。