__fastcall
Блок, относящийся только к системам Microsoft
Соглашение о вызовах __fastcall указывает, что аргументы для функций должны по возможности передаваться в регистрах. Это соглашение о вызовах применяется только к архитектуре x86. В следующем списке показана реализация этого соглашения о вызове.
Элемент |
Реализация |
---|---|
Порядок передачи аргументов |
Первые два значения DWORD или меньшие аргументы, найденные в списке аргументов слева направо, передаются в регистрах ECX и EDX; все остальные аргументы передаются в стек справа налево. |
Обязанность по обслуживанию стека |
Вызываемая функция извлекает аргументы из стека. |
Соглашение об оформлении имен |
Знак "@" добавляется к именам как префикс. Знак "@", за которым следует количество байтов (в десятичной системе счисления) в списке параметров, добавляется к именам как суффикс. |
Соглашение о преобразовании регистра |
Изменение регистра не выполняется. |
Примечание
В следующих версиях компилятора могут использовать другие регистры для сохранения параметров.
Использование параметра компилятора /Gr приводит к тому, что каждая функция в модуле компилируется как __fastcall, если функция не объявлена с конфликтующим атрибутом или именем функции не является main.
Компиляторы, предназначенные для архитектур ARM и х64, принимают и игнорируют ключевое слово __fastcall. В соответствии с соглашением на 64-разрядной микросхеме первые четыре аргумента по возможности передаются в регистрах, а дополнительные аргументы передаются в стеке. Дополнительные сведения см. в разделе Общие сведения о соглашениях о вызовах для архитектуры x64. На микросхеме ARM можно передавать в регистрах до четырех целочисленных аргументов и до восьми аргументов с плавающей запятой; дополнительные аргументы передаются в стеке.
Если используется внестрочное определение нестатической функции класса, то модификатор соглашения о вызовах не должен быть задан во внестрочном определении. То есть для нестатических методов-членов считается, что соглашение о вызовах, указанное во время объявления, было сделано в точке определения. Рассмотрим следующее определение класса:
struct CMyClass {
void __fastcall mymethod();
};
В этом случае следующий код:
void CMyClass::mymethod() { return; }
эквивалентен следующему:
void __fastcall CMyClass::mymethod() { return; }
Пример
В следующем примере аргументы передаются в функцию DeleteAggrWrapper в регистрах.
// Example of the __fastcall keyword
#define FASTCALL __fastcall
void FASTCALL DeleteAggrWrapper(void* pWrapper);
// Example of the __ fastcall keyword on function pointer
typedef BOOL (__fastcall *funcname_ptr)(void * arg1, const char * arg2, DWORD flags, ...);