簡體   English   中英

如何確定va_list是否為空

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM