2017-02-17 15 views
3

當我編寫一個「無意識的」代碼片段時,我遇到了這個問題,併成功編譯並獲得了所需的行爲。後來我注意到了這種變化的奇怪之處,並意識到我使用了一個完成函數指針typedef的逆序。現在我很困惑,如果「意外的」錯誤實際上是句法上的錯誤。在做函數指針的typedef時是*強制的嗎?

通用慣例:

typedef void* (*_malloc_fail_handler_ptr)(int) __attribute__ ((unused)); 
_malloc_fail_handler_ptr _malloc_fail_handler = NULL; 

我 「意外」 的代碼:

typedef void* (_malloc_fail_handler_ptr)(int) __attribute__ ((unused)); 
_malloc_fail_handler_ptr* _malloc_fail_handler = NULL; 

回答

5

這是正確的語法。對於第二種情況,_malloc_fail_handler_ptr的類型是函數,而不是函數指針。然後_malloc_fail_handler_ptr*的類型是指向函數的指針。因此,對於第一和第二種情況,變量_malloc_fail_handler的類型都是相同的。

+0

是的,儘管該名稱應該改爲_malloc_fail_handler_func或其他名稱,因此名稱與它是一致的:)。 (nit picking) – Rob

+0

這實際上非常有用,因爲它允許實現接口的函數被顯式聲明爲這樣做,如'extern malloc_fail_handler_t implementationor;'中所示。 – doynax

3

與所述第二個的唯一問題是命名:

typedef void* (*_malloc_fail_handler_ptr)(int) __attribute__ ((unused)); 

在那裏,_malloc_fail_handler_ptr是一個指針函數獲取int和返回void*

typedef void* (_malloc_fail_handler_ptr)(int) __attribute__ ((unused)); 

這裏,_malloc_fail_handler_ptr是一個函數獲取int和返回void*。它是一個函數類型,而不是指針類型。所以後綴_ptr是誤導性的。但像任何(在C++中,非引用)類型,您總是可以編寫T*以獲得指向T的指針,所以這可以工作。


簡化一切努力避免尷尬函數的語法,你的問題可以歸結爲:

typedef int* ptr; 
ptr x = NULL; 

與:

typedef int ptr; 
ptr* x = NULL; 

兩者都是語法很好,但第二個是很誤導命名。