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 void
和 void*
之间的区别是 C 基础知识——这是你应该在进入 [=35 之前更早学习的东西=],这是一个更高级的话题。
我写了一个用于创建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 void
和 void*
之间的区别是 C 基础知识——这是你应该在进入 [=35 之前更早学习的东西=],这是一个更高级的话题。