[英]How to determine if va_list is empty
我一直在閱讀一些編譯器支持帶有宏的va_list,並且用戶能夠用其他宏重載該功能,以便計算va_list 。
使用Visual Studio,是否可以確定va_list是否為空(aka count == 0)? 基本上我想知道這種情況:
extern void Foo(const char* psz, ...);
void Test()
{
Foo("My String"); // No params were passed
}
我最初的想法是做這樣的事情:
va_list vaStart;
va_list vaEnd;
va_start(vaStart, psz);
va_end(vaEnd);
if (vaStart == vaEnd) ...
問題在於va_end僅將參數設置為null。
#define _crt_va_start(ap,v) ( ap = (va_list)_ADDRESSOF(v) + _INTSIZEOF(v) )
#define _crt_va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
#define _crt_va_end(ap) ( ap = (va_list)0 )
沒有辦法知道通過...
傳遞了多少參數,也沒有告訴它們是什么類型。 僅當您通過其他方式(例如printf
樣式的格式字符串)告訴函數期望值時,才可以使用可變參數函數參數。 即使這樣,也無法驗證參數。
C ++ 11提供了類型安全的可變參數模板。 我不知道您的編譯器是否支持這些,或者它們是否適合您的問題。
我意識到這個問題已經很老了,但我認為將其充實可能會有所幫助。 正如Mike Seymour回答得很正確一樣,沒有絕對可靠的方法來確定va_list
的參數數量。 這就是為什么定義可變參函數的常規方法是包括具有該信息的參數,例如: void func(const char *str, int count, ...);
,它定義了呼叫者應遵守的合同。
編輯:標准(7.16.1.1.3)對於變量參數列表結尾之后的任何調用va_arg(vl, type)
實際上對va_arg(vl, type)
返回的值保持沉默。 大多數類型最常見的情況是鍵入零。 但是,CAVEAT EMPTOR-並非必須如此。
當沒有更多參數時va_arg(vl, type)
從va_arg(vl, type)
返回的值是零類型值。 對於數字類型,它是0。對於指針,它是NULL指針。 對於結構,它是所有字段都為零的結構。 如果您選擇復制va_list
並嘗試計算副本數,如下所示:
void func(const char *str, ...) {
va_list vl;
va_list vc;
int x;
int count;
count = 0;
va_start(vl, str);
va_copy(vc, vl);
do {
x = va_arg(vc, int);
if (x == 0) break;
count++;
} while (1)
va_end(vc);
.
.
. // do something, or something else,
. // based on the number of args in the list
.
va_end(vl);
您必須假設調用者將遵守合同,而不在列表中傳遞NULL或零值。 無論哪種方式,您都必須了解,可變參數函數的調用者有責任遵守規定的合同。 因此,編寫您的函數,發布合同並輕松入睡。
我知道我的答案不是“正統”答案,但是由於va_list宏的限制,我找到了以下可行的解決方案。 我們可以將va_list視為一個char數組,甚至更好的是,以null結尾的數組,因此您可以嘗試
va_list argptr;
if(strcmp(argptr,""))
{
// not empty
}
else
{
// empty
}
我嘗試了一下,對我有用。 我使用了Visual Studio 2013 Ultimate。 項目類型是Win32控制台應用程序。 沒有編譯錯誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.