2010-08-06 83 views
1

我有以下功能:VA-ARGS不解決正確

void Register(Data* _pData, uint32 _Line, const char* _pFile, ...) 
{ 
    va_list Args; 
    va_start(Args, _pFile); 
    for(uint i = 0;i m_NumFloats; ++i) 
    { 
     _pData->m_Floats[i] = va_arg(Args, fp32); 
    } 
    va_end(Args); 
} 

這是由宏調用:

#define REG(_Name, ...)\ 
{\ 
    if(s_##_Name##_Data.m_Enabled) 
     Register(&s_##_Name##_Data, __LINE__, __FILE__, ##__VA_ARGS__);\ 
}\ 

用法用量:

REG(Test, (fp32)0.42f); 

數據 - 結構看起來像:


struct Data 
{ 
    int m_NumFloats; 
    fp32 m_Floats[4]; 
} 

Data的創建宏將創建靜態的Data g_YourName_Data並使用最多4個m_NumFloats正確初始化它。

va_arg調用解析爲0.0。存在s_Test_Data並且註冊函數被稱爲適當的。 va-list只是簡單地不會讓我將第一個參數解析到我傳入的float中。有什麼具體的我失蹤?

+2

什麼是_Name_Data?爲什麼當你的宏定義沒有在任何地方使用'_Name'時,你在宏中聲明'_Name'參數? '__VA_ARGS__'前的'##'是什麼? – AnT 2010-08-07 00:08:44

+0

沒有'_Name_Data'。這是一個使用'_Name'來查找靜態聲明對象的宏,在這種情況下,這個對象會擴展爲'_Test_Data'。所以宏使用'_Name'。如果沒有實際的額外參數傳遞,'##'用於剝離','。 – Simon 2010-08-07 07:34:18

+0

@AndreyT「__VA_ARGS__'前的##是什麼?」 - 它使可變宏接受零參數成爲可能。 – 2013-12-18 12:06:07

回答

2

嘗試:

#define REG(_Name, ...)\ 
{\ 
    if(s_##_Name_Data.m_Enabled)\ 
     Register(&s_##_Name_Data, __LINE__, __FILE__, __VA_ARGS__);\ 
} 

擺脫標記粘貼運算符。你我們也在你的宏中缺少一個'\'(也許是複製粘貼錯誤?)。

另外,使用va_arg()而不是va_args()。我不確定你的意思是_Name_Name_Data還是其他方式。

最後,我認爲fp32float的別名;海灣合作委員會有這樣對我說:

C:\TEMP\test.c:22: warning: `fp32' is promoted to `double' when passed through `...' 
C:\TEMP\test.c:22: warning: (so you should pass `double' not `fp32' to `va_arg') 
C:\TEMP\test.c:22: note: if this code is reached, the program will abort 

你應該留意這個警告。如果我不這樣做,程序確實會崩潰。

+3

',## __VA_ARGS__'是一個GCC擴展,如果'__VA_ARGS__'展開爲無記號(即只有一個參數調用REG(),逗號就會消失)。在*這種情況下*這是不適當的,因爲Register()必須至少接收一個匿名參數,並且您希望在運行時是編譯錯誤而不是垃圾,但它不會自動錯誤。 – zwol 2010-08-07 00:35:11

+0

@Zack - 感謝那些信息。我知道GCC有辦法處理空的'__VAR_ARGS__',但不記得那是它。 – 2010-08-07 02:33:13

+0

感謝Michael的回答,並對於複製粘貼錯誤感到抱歉。我將編輯帖子以使其正確。我沒有收到任何此類警告。真正的代碼處理不存在va-args的情況,預期的參數數量在前面定義。如果你真的在宏的最後一行附加了一個額外的'\'?我很肯定你不需要這樣做(因爲我有幾個沒有它的宏,如果沒有的話它會導致一些編譯錯誤)。 '_Name'被插入到我們正在訪問的標識符中。在這種情況下,標識符將變成's_Test_Data'。 – Simon 2010-08-07 07:28:29

相關問題