2012-07-28 32 views
1

根據我讀到的有關va_arg宏,它檢索參數列表指向的下一個參數。有什麼辦法可以選擇我想得到的參數的索引,比如數組索引?va_start as array

例如,我需要做一個操作,我需要調用至少3倍的va_arg宏,但我希望那些3次檢索相同的參數,而不是列表中的下一個。一種解決方案可能是使用一個函數並傳遞參數,但我不希望這樣。

此外,如果沒有其他宏能夠做到這一點,我怎麼可以通過指針引用數組參數的開始?我知道它不是便攜式的,不是類型安全的等等,只是爲了學習。

這裏是我要如何實現它的示例代碼:

bool SQLBase::BindQuery (char* query, int NumArgs, ...) 
{ 
    va_list argList; 
    va_start(argList, NumArgs); 
    SQLPrepare (hstmt, query, SQL_NTS); 
    for (int x = 0; x < NumArgs; x++) 
    { 
     SQLBindParameter (hstmt, (x+1), GetTypeParameter (va_arg(argList, SQLPOINTER*), SQL_C_CHAR, SQL_CHAR, 10, 0, va_arg(argList, SQLPOINTER*), va_arg(argList, SQLLEN), &recvsize[x]); 
    } 

那麼va_arg就被稱爲3次SQLBindParameter函數,我想第2次指向同一個說法,不增加參數列表中的計數成員。

+1

將其返回值分配給一個變量。 – 2012-07-28 06:34:05

+1

什麼是阻止你使用變量? 'SQLPOINTER * tmp = va_arg(argList,SQLPOINTER *);'這樣你就不必爲相同的參數使用var_arg兩次了。你的代碼的另一個問題是C++不保證從左到右評估參數,所以不能保證你的哪個va_arg調用會先發生。 – jahhaj 2012-07-28 06:35:28

+0

沒有大聲笑,我只是問是否有任何宏,讓我作爲一個數組訪問參數列表,它只是爲了知道。謝謝 – ffenix 2012-07-28 06:38:08

回答

1

首先,在你的函數調用中多次調用va_arg是多毛的,因爲你不知道這些調用以何種順序發生。你需要事先做到這一點,所以你的參數以正確的順序被檢索。

二,no:沒有數組風格的用法auf va_list。這是因爲va_list不知道堆棧上的參數;您在va_arg調用中提供了該類型,然後va_arg可以增加va_list中包含的(內部/概念性)指針,因爲它知道該參數的大小。進入第三個參數將需要您提供前兩個類型。

如果所有的參數都是相同的大小(如「void *」),你總是可以做一個循環,調用va_arg適當的次數。如果您可以合理確信您的論點實際上具有相同的規模,則這種「便攜式」便攜式。但我不太相信這樣做是最好的行動方式 - 需要這樣做可能意味着不同的設置會更合適,例如首先傳遞數組而不是使用可變參數功能。

您也可以只取一個函數參數的地址,並假定它們以某種順序位於堆棧上。這是非常不可移植的,因爲您需要了解編譯器之間可能會有所不同的調用約定,甚至可能會根據編譯選項進行更改。我肯定會建議不要做這樣的事情。