Вопрос

Насколько я знаю, только Caller-Clean-Stack Convention может использовать переменные аргументы.
Кстати, Winapi StringCChPrintfw объявляется таким образом. (Я удалил Сал)

__inline Hresult. __stdcall.
Stringcchprintfw (
Strsafe_lpwstr pszdest, size_t cchdest, strsafe_lpcwstr pszformat, ...
);

Могут ли stdcall иметь переменные аргументы?

Это было полезно?

Решение

Нет stdcall. Конвенция о вызове имеет Callee Clean The Stack. Поскольку Callee убирает стек, нет способа, чтобы он не знал во время компиляции, сколько выскочить, поэтому он не может иметь переменных аргументов.

Для того, чтобы иметь переменное количество аргументов функций, вам нужно использовать CDECL, который имеет абонент очистить стек. Это все компиляторы, чтобы определить, сколько аргументов передаются, и поскольку вызывающий абонент убирает стек, он также знает, сколько отображать стек, когда вызов на функцию возвращает.

В случае, упомянутое выше, функция объявляется использовать __stdcall, который, как упомянул ранее, не поддерживает переменные аргументы. В этом случае компилятор принимает решение игнорировать Конвенцию о вызове, определенную и вернуться к __cdecl. Отказ Это поведение намерено в описании для stdcall., упомянутый выше. Я цитирую:

Callee очищает стек, поэтому компилятор делает варярг функции __cdecl..

Это можно соблюдать, если следующий код компилируется и вызов функции разобран.

int __stdcall Bar(int a, int b, ...)
{
  return b * a;
}

Полученный код будет рассматриваться как __cdecl. Отказ Как к тому причина Это определено так, я не знаю.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top