__cdecl
Блок, относящийся только к системам Майкрософт
По умолчанию для программ на языках C и C++ используется соглашение о вызовах __cdecl. Поскольку стек очищается вызывающим объектом, он может выполнять функции vararg. Соглашение о вызовах __cdecl создает исполняемые файлы большего размера, чем __stdcall, так как для него необходимо, чтобы вызов функции содержал код очистки стека. В следующем списке показана реализация этого соглашения о вызове.
Элемент |
Реализация |
---|---|
Порядок передачи аргументов |
Справа налево. |
Обязанность по обслуживанию стека |
Вызывающая функция выводит аргументы из стека. |
Соглашение об оформлении имен |
Перед именами ставится символ подчеркивания (_), кроме случаев экспорта функций __cdecl, использующих компоновку С. |
Соглашение о преобразовании регистра |
Изменение регистра не выполняется. |
Примечание
Дополнительные сведения см. в разделе Внутренние имена.
Задайте модификатор __cdecl перед именем переменной или функции. Поскольку по умолчанию используются соглашения об именовании и вызовах C, то __cdecl может использоваться в коде x86 только в тех случаях, когда указан параметр компилятора /Gv (vectorcall), /Gz (stdcall) или /Gr (fastcall). Параметр компилятора /Gd принудительно устанавливает соглашение о вызовах __cdecl.
На процессорах ARM и x64 __cdecl принимается, но обычно игнорируется компилятором. По соглашению на ARM и x64 аргументы передаются в регистрах, когда это возможно, а последующие аргументы передаются в стек. В коде x64 используйте __cdecl, чтобы переопределить параметр компилятора /Gv и использовать соглашение о вызовах по умолчанию для x64.
Если используется внестрочное определение нестатической функции класса, то модификатор соглашения о вызовах не должен быть задан во внестрочном определении. То есть для нестатических методов-членов считается, что соглашение о вызовах, указанное во время объявления, было сделано в точке определения. Рассмотрим следующее определение класса:
struct CMyClass {
void __cdecl mymethod();
};
В этом случае следующий код:
void CMyClass::mymethod() { return; }
эквивалентен следующему:
void __cdecl CMyClass::mymethod() { return; }
Пример
В следующем примере компилятору дается инструкция использовать для функции system соглашения об именовании и вызовах C:
// Example of the __cdecl keyword on function
int __cdecl system(const char *);
// Example of the __cdecl keyword on function pointer
typedef BOOL (__cdecl *funcname_ptr)(void * arg1, const char * arg2, DWORD flags, ...);