2014-02-12 2 views
1

Я пытаюсь использовать pthread_once для инициализации некоторого кода. Но называть init_routine() по
{1} вызывает во время компиляции предупреждение - предупреждение: проходя аргумент 2 из «pthread_once» от несовместимого типа указателя, в то время как с помощью
{2} не дает каких-либо предупрежденийПередача функции как аргумент pthread_once

В file1 .c

int init_routine (void) { 
// initialize variables 
} 

В file1.h

int init_routine(void); 

Теперь я включаю file1.h в file2.c

В 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' и включен в файл file2.c из файла file1.h. – 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, но он все равно должен работать практически с любым компилятором в общем пользовании сегодня. gcc, например, выдаст предупреждение, и только если вы используете переключатель -pedantic.

+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

Смежные вопросы