Почему существует так много разных соглашений о вызовах? - PullRequest
8 голосов
/ 07 августа 2010

Исторически сложилось так, почему кажется, что почти все и их младший брат определили свои собственные соглашения о вызовах? У вас есть C, C ++, Windows, Pascal, Fortran, Fastcall и, вероятно, еще миллион других, о которых я даже не думал упоминать. Разве одно соглашение не должно быть наиболее эффективным для подавляющего большинства вариантов использования? Есть ли когда-нибудь веская причина, чтобы предпочесть одно другому?

Ответы [ 5 ]

10 голосов
/ 07 августа 2010

Упомянутые вами соглашения о вызовах были разработаны на протяжении десятилетий для разных языков и различного оборудования. У всех были разные цели. cdecl поддерживает переменные аргументы для printf. Результатом stdcall стал меньший код gen, но без переменных аргументов. Fastcall может значительно повысить производительность простых функций, используя только один или два аргумента на старых машинах (но сегодня это редко ускоряет работу).

Обратите внимание, что когда была представлена ​​x64, по крайней мере, в Windows она была разработана для единого соглашения о вызовах.

Рэймонд Чен написал большую серию по истории соглашений о вызовах, вы можете начать здесь .

1 голос
/ 07 августа 2010
  • Некоторые из них более эффективны в отношении производительности, а другие более эффективны в размере кода.
  • Некоторые функции (количество переменных переменных) поддерживаются только с некоторыми соглашениями.

Дополнительная информация: http://en.wikipedia.org/wiki/X86_calling_conventions

1 голос
/ 07 августа 2010

Потому что исторически каждый и их младший брат определяли свои собственные правила вызова. Все они были созданы для разных целей и, следовательно, руководствовались разными требованиями к производительности. Например, C ++ поддерживает оптимизацию для передачи параметра this.

0 голосов
/ 07 августа 2010

Они созданы для разных целей и с разными системами оптимизации.

Например, чтобы уменьшить «Переполнение стека» (без каламбура), некоторые люди думали о различных идеях вызова функции, чтобы сделать переполнение стека невозможным.

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

0 голосов
/ 07 августа 2010

Частично причина заключается в архитектуре микропроцессора (или процессора). Большинство языков запускаются на конкретном процессоре и немного запутываются в этой архитектуре. Например, старый компьютер серии Univac 1100 даже не имел стека вызовов!

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

...