關於gnu's C的文檔指出如果函數具有__attribute__((sentinel))
它必須具有NULL
作爲該函數的最後一個參數。如何使用自定義標記值創建可變參數函數?
是否可以有任何其他值作爲結束參數列表的標記?
關於gnu's C的文檔指出如果函數具有__attribute__((sentinel))
它必須具有NULL
作爲該函數的最後一個參數。如何使用自定義標記值創建可變參數函數?
是否可以有任何其他值作爲結束參數列表的標記?
如果您足夠了解它,可以使用任何想要標記參數列表末尾的值來從參數列表中抓取它。不過,編譯器通常不會檢查您選擇的值是否在調用函數時實際傳遞,因此您需要小心。
本質上你只是以通常的方式創建一個可變參數函數,而當你閱讀一個與你的哨兵匹配的函數時,你停止閱讀參數的函數 - 沒有什麼特別的要做,但你需要知道什麼類型的參數來閱讀。
例如:
#include <stdarg.h>
/* Count arguments up to the number 5 */
int countArgsTilFive(int first, ...)
{
int res = 1;
va_list ap;
if (first == 5) return 0;
va_start(ap,first);
while (va_arg(ap,int) != 5) res++;
va_end(ap);
return res;
}
...將計算其所有5
之前發生爭論。如果你不通過5
列表中的某處,或者你傳遞的參數不是int
,那麼可能會發生壞事。
與指針,其中前哨淋巴結作爲第一過去了,再次作爲最後一個參數又如:
/* Count arguments, excluding the first, until the first occurs again */
int countPtrs(void *sentinel, ...)
{
int res = 0;
va_list ap;
va_start(ap,sentinel);
while (va_arg(ap,void *) != sentinel) res++;
va_end(ap);
return res;
}
使用GCC的'__attribute __((sentinel))'編譯器_can_檢查參數列表是否以給定的值結束。只是它允許的唯一值是'NULL' - 它不會讓您爲編譯器選擇另一個值來驗證。 –
如果他只是想知道是否有像__attribute __((sentinel))這樣的任意哨兵值,那麼答案就沒有那麼有用了,但是如果關於__attribute __((sentinel))的東西留下了印象非空哨兵根本無法使用,它應該清除它。 – Dmitri
這是(經過編輯下來的版本)蘋果如何定義得心應手NS_REQUIRES_NIL_TERMINATION
預編譯檢查,即需要一些方法的零定點...
+ (NSArray*)arrayWithRects:(NSR)rect,...NS_REQUIRES_NIL_TERMINATION;
#if !defined(NS_REQUIRES_NIL_TERMINATION)
#if defined(__APPLE_CC__) && (__APPLE_CC__ >= 5549)
#define NS_REQUIRES_NIL_TERMINATION __attribute__((sentinel(0,1)))
#else
#define NS_REQUIRES_NIL_TERMINATION __attribute__((sentinel))
#endif
#endif
不太清楚的differenc e是在這兩個編譯器指令之間..但我認爲這個結構可以與「其他」,「定製」哨兵一起使用..我在想NSNotFound
- XX_REQUIRES_NSNOTFOUND_TERMINATION
或類似的東西?
至於創建這樣的功能,顯然你可以做到這一點。我不知道任何GNU擴展,以檢查任意可變參數方案的參數是否正確。他們甚至沒有一個屬性可以將參數標記爲給出了多少個參數的「計數」,以便編譯器可以檢查它們是否正確。 –