передача многоточия в другую переменную функцию

<p>у меня есть около 30 функций variadic. каждый принимает путь в качестве последнего аргумента, например:</p><pre><code>bool do\_foo(struct *f, int q, const char *fmt, ...) </code></pre><p>в каждой функции я должен проверить, что расширенный формат меньше или равен определенному размеру. итак, я обнаружил, что копирую/вставляю тот же кусок кода, чтобы проверить, сколько символов <code>vsnprintf()</code> не напечатало, соответственно установил <code>errno</code> и вывел из записи.</p><p>я хотел бы написать для этого функцию, которая будет возвращать статически размещенную (расширенную) строку, которая, как известно, имеет безопасный размер, или новую инициализированную строку при ошибке, которая может быть проверена на null. проверки также должны определить, является ли строка абсолютным или относительным путем, который влияет на безопасный размер строки. это много повторяющегося кода, и он начинает пахнуть.</p><p>есть ли способ, которым я могу передать содержимое elipsis из записи моей функции в другую функцию? или я должен сначала вызвать <code>va\_start()</code>, а затем передать <code>va\_list</code> вспомогательной функции?</p><p><strong>edit:</strong></p><p>я вовсе не против передачи <code>va\_list</code> помощнику, я просто хотел убедиться, что больше ничего не существует. мне кажется, что компилятор понимает, где начинаются переменные аргументы, поэтому мне было просто любопытно, могу ли я сказать, чтобы они передавались вместе.</p>

<p>вы не можете, вы можете передавать аргументы только как <code>va\_list</code>. смотрите <a href="http://c-faq.com/varargs/handoff.html">comp.lang.c faq</a> .</p><p>в общем, если вы пишете функции с переменным числом (то есть функции, которые принимают переменное число аргументов) в c, вы должны написать две версии каждой функции: одну, которая принимает многоточие (<code>...</code>), и одну, которая принимает <code>va\_list</code> , версия с ellipsis должна вызвать <code>va\_start</code>, вызвать версию с <code>va\_list</code>, вызвать <code>va\_end</code> и вернуться. нет необходимости дублировать код между двумя версиями функции, так как одна вызывает другую.</p>

<p>вероятно, вы можете использовать переменные макросы - вот так:</p><pre><code>#define foo(...) do { do\_some\_checks; myfun(\_\_va\_args\_\_); } while (0) </code></pre><p><strong>nb!</strong> variadic макросы только для c99</p>

<p>я не знаю, поможет ли это, вы можете получить доступ к переменным по ссылке. это своего рода хитрый трюк, но, к сожалению, он не позволит вам использовать ellipsis в окончательном определении функции.</p><pre><code>#include <stdio.h> void print\_vars(int *n) { int i; for(i=0;i<=*n;i++) printf("%x %d ", (int)(n+i), *(n+i)); printf("\n"); } void pass\_vars(int n, ...) { print\_vars(&n); } int main() { pass\_vars(4, 6, 7, 8, 0); return 0; } </code></pre><p>на моем пк это выводит</p><pre><code>$ ./a.out bffeb0b0 4 bffeb0b4 6 bffeb0b8 7 bffeb0bc 8 bffeb0c0 0 </code></pre>

<p>вы должны передать va\_list помощнику.</p>