У меня есть следующая функция:
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];
}
Макрос создания данных создает статические данные g_YourName_Data
и правильно инициализирует их с максимум 4 m_NumFloats.
Вызов va_arg разрешается до 0.0. s_Test_Data существует, и функция Register называется соответствующей. va-list просто не позволит мне разрешить первый аргумент в float, в который я его передал. Есть что-то конкретное, что я упускаю?
Попробуйте:
#define REG(_Name, ...)\
{\
if(s_##_Name_Data.m_Enabled)\
Register(&s_##_Name_Data, __LINE__, __FILE__, __VA_ARGS__);\
}
Избавьтесь от оператора вставки токена. Вам также не хватает символа '\' в вашем макросе (возможно, ошибка копирования и вставки?).
Также используйте va_arg ()
, а не va_args ()
. И я не уверен, что вы имели в виду, что _Name
должно быть _Name_Data
или наоборот.
Наконец, я предположил, что fp32
был псевдонимом для float
; GCC сказал мне следующее:
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
Вы должны прислушаться к этому предупреждению. Если я этого не сделаю, у меня произойдет сбой программы.