Соглашение о вызовах должно быть таким, когда вызывающий объект очищает аргументы из стека (поскольку вызываемый не знает, что будет передано).
Это не обязательно соответствует тому, что Microsoft называет «__cdecl». Например, в SPARC он обычно передает аргументы в регистрах, потому что именно так SPARC предназначен для работы - его регистры в основном действуют как стек вызовов, который передается в основную память, если вызовы становятся достаточно глубокими, чтобы они больше не будут вписываться в реестр.
Хотя я менее уверен в этом, я ожидал бы примерно то же самое на IA64 (Itanium) - у него также есть огромный набор регистров (пара сотен, если память служит). Если я не ошибаюсь, это немного более уместно в том, как вы используете регистры, но я ожидаю, что он будет использоваться аналогично, по крайней мере, большую часть времени.
Почему это важно для вас? Смысл использования stdarg.h и его макросов состоит в том, чтобы скрыть различия в соглашении о вызовах от вашего кода, чтобы он мог работать с переменными аргументами переносимо.
Редактировать, основываясь на комментариях: Хорошо, теперь я понимаю, что вы делаете (по крайней мере, достаточно, чтобы улучшить ответ). Учитывая, что у вас (по-видимому) уже есть код для обработки изменений в стандартном ABI, все проще. Это оставляет только вопрос о том, всегда ли функции с переменными значениями используют «ABI по умолчанию», какой бы она ни была для данной платформы. С «stdcall» и «default» в качестве единственных опций, я думаю, что ответ на этот вопрос - да. Например, в Windows wsprintf
и wprintf
нарушают эмпирическое правило и используют соглашение о вызовах cdecl вместо stdcall.