2013-06-26 36 views
2

爲什麼在這裏使用三個*? (glibc的源代碼的glibc-2.9/sysdeps /馬赫/位/的libc-lock.h線81)爲什麼在glibc libc-lock.h中使用三個*?

在線視圖的libc-lock.h代碼 - >http://www.oschina.net/code/explore/glibc-2.9/sysdeps/mach/bits/libc-lock.h

/* Start a critical region with a cleanup function */ 
#define __libc_cleanup_region_start(DOIT, FCT, ARG)    \ 
{                \ 
    typeof (***(FCT)) *__save_FCT = (DOIT) ? (FCT) : 0;   \ 
    typeof (ARG) __save_ARG = ARG;        \ 
/* close brace is in __libc_cleanup_region_end below. */ 

/* End a critical region started with __libc_cleanup_region_start. */ 
#define __libc_cleanup_region_end(DOIT)       \ 
if ((DOIT) && __save_FCT != 0)         \ 
    (*__save_FCT)(__save_ARG);         \ 
} 

我不知道爲什麼使用3 *這裏,爲什麼不是

typeof (*(FCT)) * __save_FCT = (DOIT) ? (FCT) : 0; 

在此先感謝。

+0

因爲它意味着不同的東西,也許? – 2013-06-26 08:19:04

+2

它是否返回指向指針的指針? – Neil

+0

如果我作爲單個指針給出時沒有問題,那麼在使用'__save_FCT'時可能會收到編譯器警告。因爲當'FCT'是'****'類型時,'__save_FCT'應該是單個指針。否則,當以((*(FCT))給出時,'__save_FCT'會變成三重指針。 - 我的猜測仍然存在。 – VoidPointer

回答

1

我想這是爲了確保FCT是一個函數指針。當一個函數指針被解引用時,它返回一個「函數指示符」。 C99 6.5.3.2/4「地址和間接運算符」說:

一元*運算符表示間接。如果操作數指向一個函數,結果是一個函數標識符

而且很像數組名稱,函數指示符在一些情況下計算爲函數指針。 C99 6.3.2.1/4「左值,數組和函數指示符」:

函數指示符是一個具有函數類型的表達式。除了它是sizeof運算符的操作數或一元運算符以外,類型爲「函數返回類型」的函數標識符被轉換爲具有類型「指向函數返回類型的指針」的表達式。

因此,您可以將函數指針(或函數名稱)解引用任意次數,並且仍然以「函數返回類型」的指示符結束。

所以我認爲如果使用函數指針以外的其他函數指針用於FCT宏參數,那麼我認爲三重deref可以讓編譯器投訴。

+0

非常感謝:)如果是這樣,它應該是:typeof(***(FCT))* __ save_FCT =(DOIT)? (**(FCT)):0; // 2最後一次FCT之前的deref –

+0

我在11年前發現了評論 - > http://sourceware.org/git/?p=glibc.git;a=commitdiff;h=4ffd4002c7282cfe84f394a93fb5ad082be1820f'語法,所以函數和指針函數參數都能正常工作' –

+0

@zhao_x_g:很好找(我正在考慮嘗試挖掘那套代碼中的「責備」,但決定我太懶惰了)。所以看起來這種變化利用了我所說的行爲,但是具有不同的動機。 –

相關問題