Functions
F.55
Не используйте аргументы `va_arg`
Причина
Чтение из va_arg предполагает, что был передан правильный тип. Передача в varargs предполагает, что будет прочитан правильный тип. Это ненадёжно, поскольку в общем случае нельзя гарантировать безопасность в языке, и поэтому полагается на дисциплину программиста для правильной реализации.
Пример
int sum(...)
{
// ...
while (/*...*/)
result += va_arg(list, int); // ПЛОХО, предполагает передачу int-ов
// ...
}
sum(3, 2); // ok
sum(3.14159, 2.71828); // ПЛОХО, неопределённо
template<class ...Args>
auto sum(Args... args) // ХОРОШО, и гораздо гибче
{
return (... + args); // примечание: C++17 «fold expression»
}
sum(3, 2); // ok: 5
sum(3.14159, 2.71828); // ok: ~5.85987
Альтернативы
- перегрузка
- вариадические шаблоны
- аргументы
variant initializer_list(однородные)
Примечание
Объявление параметра ... иногда полезно для техник, не связанных с фактической передачей аргументов, в частности для объявления функций «принимающих всё», чтобы отключить «всё остальное» в наборе перегрузок или выразить перехватывающий случай в метапрограммировании шаблонов.
Контроль
- Выдавать диагностику при использовании
va_list,va_startилиva_arg. - Выдавать диагностику при передаче аргумента в параметр vararg функции, которая не предлагает перегрузку для более специфичного типа на позиции vararg. Исправление: использовать другую функцию или
[[suppress("type")]].