2014-02-12 173 views
1

我想用pthread_once来初始化一些代码。但调用由
的init_routine() {1}导致编译时警告 - 警告:传递来自兼容的指针类型“调用pthread_once”的参数2,而使用
{2}不给出任何提示传递函数作为参数pthread_once

file1中.C

int init_routine (void) { 
// initialize variables 
} 

在file1.h

int init_routine(void); 

现在我包括file2.c中的file1.h

在file2.c中

#include "file1.h" 

pthread_once_t prog_inited = PTHREAD_ONCE_INIT; 

int start() { 
... 
pthread_once(&prog_inited, &init_routine);  <-- {1} 
pthread_once(&prog_inited, (void *)init_routine); <-- {2} 

... 
return 0; 
} 

的是这之间的区别?

谢谢。

+0

你的'init_routine'声明是什么?如果是'extern void init_routine()',你可能需要将它改为'extern void init_routine(void)' –

+0

@JosephQuinsey刚刚编辑了这个问题。 'init_routine()'有一个返回类型'int',并且包含在file1.h中的file2.c中。 – adizone

+0

因此,将返回类型从'int'更改为'void'可能会解决您的问题 –

回答

0

(答到更新的问题)在你的头文件,你需要改变:

int init_routine(void); 

void init_routine(void); 

并调用pthread_once不需要init_routine&前:

pthread_once(&prog_inited, init_routine); 

但是你原本有什么,即:

pthread_once(&prog_inited, (void *)init_routine); 

就是,如图cnicutar,没有严格的法律C代码所指出的,但它仍然可与几乎普遍使用的今天所有编译工作。例如,只有在使用-pedantic开关时,才会发出警告,例如gcc

+0

有同样的警告是否有另一种方法,而不是改变init_routine的返回类型? – adizone

+0

你的'(void *)'应该没问题。或者铸造'(void(*)(void))'。但是,如果你想成为100%迂腐的人,你可以写一个正确类型的单行包装:void my_init_routine(void){init_routine();}'。包装甚至可以检查原始返回值,如果它有用的话。 –

+0

这是使用包装保持清洁的绝佳建议。非常感谢 ! – adizone

0

调用调用pthread_once正确的语法是:

int pthread_once(pthread_once_t *once_control, void (*init_routine)(void)); 

所以你的情况通话将需要:

pthread_once(&prog_inited, init_routine); 

(void *)实际上是没有必要的,错误的,因为(void *)不是函数指针类型和由标准你不允许这样的演员!

+0

但是,为什么我会收到{1}的编译器警告。如果我使用:'pthread_once(&prog_inited,init_routine);' – adizone