2014-02-12 182 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