Что такое пользовательские соглашения о вызовах? - PullRequest
7 голосов
/ 23 февраля 2010

Что это? И как на меня это влияет как на разработчика?

Связанный:
Какие существуют соглашения о вызовах в C / C ++ и что они означают?

Ответы [ 4 ]

10 голосов
/ 23 февраля 2010

A соглашение о вызовах описывает, как что-то может вызывать другую функцию. Это требует передачи параметров и состояния другой функции, чтобы она могла правильно выполнять и возвращать управление. Способ, которым это делается, должен быть стандартизирован и определен, чтобы компилятор знал, как упорядочить параметры для потребления вызываемой удаленной функцией. Существует несколько стандартных соглашений о вызовах, но наиболее распространенными являются fastcall, stdcall и cdecl.

Обычно термин пользовательское соглашение о вызовах является немного неправильным и относится к одной из двух вещей:

  • Нестандартное соглашение о вызовах или соглашение, которое не широко используется (например, если вы строите архитектуру с нуля).

  • Специальная оптимизация, которую может выполнить компилятор / компоновщик, использующий соглашение об одноразовом вызове с целью повышения производительности.

В последнем случае это приводит к тому, что некоторые значения, которые иначе были бы помещены в стек, вместо этого будут сохраняться в регистрах. Компилятор попытается принять это решение, основываясь на том, как параметры используются внутри кода. Например, если параметр будет использоваться в качестве максимального значения для индекса цикла, так что индекс сравнивается с максимальным на каждой итерации, чтобы увидеть, должны ли вещи продолжаться, это было бы хорошим случаем для его перемещения в регистр.

Если оптимизация выполняется, это обычно уменьшает размер кода и повышает производительность.

И как на меня это влияет, как на разработчика?

С вашей точки зрения, как разработчика, вам, вероятно, все равно; это оптимизация, которая произойдет автоматически.

1 голос
/ 23 февраля 2010

Я не думаю, что вам действительно нужно заботиться.

Обычные соглашения о вызовах - это такие вещи, как __stdcall и __fastcall. Они определяют, как ваша подпись вызова преобразуется в макет стека, кто (вызывающий или вызывающий) отвечает за сохранение и восстановление регистров и т. Д. Например, __fastcall должен использовать больше регистров, где __stdcall будет использовать больше стека.

Пользовательские соглашения о вызовах оптимизированы специально для конкретной функции и способа ее использования. Они происходят, IIRC, только для функций, которые являются локальными для определенного модуля. Вот почему компилятор так много знает о том, как он используется, а также о том, что вам не нужно, чтобы внешний вызывающий мог указывать соглашение.

Исходя из этого, ваш компилятор будет использовать их автоматически, где это необходимо, ваш код будет работать немного быстрее и / или занимать немного меньше места, но вам не нужно об этом беспокоиться.

1 голос
/ 23 февраля 2010

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

Иногда используется соглашение, отличное от стандартного, которое называется пользовательским соглашением о вызовах.

Это наиболее часто встречается при взаимодействии между разными языками. Например, C и Pascal имеют разные соглашения о том, как передавать параметры. С точки зрения C, соглашение о вызовах Pascal можно назвать пользовательским соглашением о вызовах.

0 голосов
/ 23 февраля 2010

Если вы непосредственно не управляете стеком или не пишете встроенную сборку, ссылающуюся на локальные переменные, это не влияет на вас. Или если ваш интерфейс с библиотеками связан с различными соглашениями о вызовах

Что это такое: Большинство компиляторов и т.п. используют стандартное соглашение о вызовах, такое как cdecl, где аргументы функции помещаются в стек в определенном порядке и тому подобное.

...