2010-08-06 82 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

相关问题