va_list
имеет некоторые недостатки, связанные с занижением аргументов функции:
- при вызове такой функции компилятор не знает, какие типы
Ожидаются аргументы, поэтому стандарт навязывает некоторые «обычные
преобразование ", прежде чем аргументы передаются в функцию. Например, все
продвигаются целые числа, которые
int
, все float
повышен до double
. В некоторых случаях вы не получили то, что вы
хотел в вызываемой функции.
- В вызываемой функции вы указываете компилятору, какой тип аргумента
ты ожидаешь и сколько их. Нет никаких гарантий, что звонящий все правильно понял.
Если вы в любом случае передаете число аргументов, и они относятся к одному и тому же известному типу, вы можете просто передать их с помощью временного массива, написанного для C99:
void add_vertices(graph G, vertex v, size_t n, vertex neigh[n]);
Вы бы назвали это что-то вроде этого
add_vertices(G, v, nv, (vertex []){ 3, 5, 6, 7 });
Если это соглашение о вызовах кажется вам слишком уродливым, вы можете заключить его в макрос
#define ADD_VERTICES(G, V, NV, ... ) add_vertices((G), (V), (NV), (vertex [NV]){ __VA_ARG__ })
ADD_VERTICES(G, v, nv, 3, 5, 6, 7);
здесь ...
указывает на похожую концепцию для макросов. Но результат намного безопаснее, поскольку компилятор может выполнить проверку типа, и это не задерживается на выполнение.