Насколько я знаю, с C ...
функция вызывающей стороны помещает аргументы в стек в порядке справа налево.
вызывающая сторона отвечает за удаление аргументов из стека после выполнения вызываемой функции. Вероятно, это именно потому, что вызывающей стороне гарантированно известно, сколько аргументов она помещает в стек, а вызываемая функция может ошибиться.
P.S .: Соглашения о вызовах обычно зависят от реализации . То, что я только что описал, известно как соглашение о вызовах "cdecl". Сравните это с соглашением о вызовах, обычно известным как "stdcall", где вызываемая функция отвечает за удаление своих аргументов из стека. По этой причине он не поддерживает списки аргументов переменной длины.
P.P.S.: Как прокомментировал пользователь nategoose, я не упомянул, как списки аргументов переменных на самом деле используются . Смотрите, например документация POSIX для заголовка <stdarg.h>
для получения дополнительной информации.