当我查看pthread_create的概要时,我想起了这个问题:
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
我不明白为什么第三个参数必须那么复杂。它的目的只是传递一个函数地址。那么他们为什么不使用
void (*start_routine)(void *)
甚至
void (start_routine)(void *)
一般情况下,我们应该在什么情况下使用像上面第三个参数那样的函数签名?
答案 0 :(得分:3)
C函数指针语法非常丑陋且难以理解。基本上答案是它必须是这样的,因为C的设计者决定这样做。
void *(*start_routine) (void *)
引用一个指向函数的指针,取一个void *
类型的参数,然后返回void *
。
您提供的第一个示例,void (*start_routine)(void *)
也是一个函数指针,并且还带有void *
参数,但不返回任何内容。
另一个例子,void (start_routine)(void *)
不是函数指针,它不返回任何内容。括号在那里并没有真正起任何作用,它与写void start_routine(void *)
是一样的,我很确定不允许它作为参数类型。
编辑:实际上允许一个作为参数,但它没有被广泛使用,但仍然有错误的返回类型。
希望能够解决问题。
答案 1 :(得分:2)
让我们看看cdecl对此有何看法:
将start_routine声明为指向函数的指针(指向void的指针),返回指向void
的指针
第一个void *
表示该函数返回一个通用指针。 (*start_routine)
表示参数是指针(指向函数)。 (void *)
表示该函数采用单个参数,即通用指针。
答案 2 :(得分:0)
start_routine使用void*
来允许线程启动器将一些任意数据传递给新线程。它返回void*
,以便线程可以向调用者返回一个有意义的退出代码(而不是显式地必须从线程函数调用pthread_exit
)。
请注意,您的第二个建议(void (start_routine)(void*)
不是函数指针,因此不是pthread_create
或任何其他函数的参数选项。