Хорошо, я нашел обходной путь:
#define ASSERT_LIST_TYPE(t, l...) do{t _t[] = {l};}while(0)
void _Log(char* what, ...);
#define Log(what, args...) do{\
ASSERT_LIST_TYPE(char*, args);\
_Log(what, args);\
}while(0)
Это, по крайней мере, генерирует предупреждение, если аргументы имеют неправильный тип, потому что инициализация фиктивного массива имеет неправильный тип.
Я планирую #ifdef вывести ASSERT_LIST_TYPE, если это не отладочная сборка, на всякий случай.
** Редактировать **
Основываясь на отзывах здесь, я изменил код, чтобы он выглядел так:
void _Log(char* what, const char** args, size_t args_len);
#define Log(what, args...) do{\
const char* a[] = {args};\
_Log(what, a, (sizeof a)/sizeof(char*));
}while(0)
Кажется, это работает, даже если args пуст, и он ловит кого-то, передающего литеральную строку obj-c вместо (@"..." вместо "..."), что и укусило меня раньше.
person
Mark Pauley
schedule
23.01.2014