Исторически, почему кажется, что почти все и их младший брат определили свои собственные соглашения о вызовах? У вас есть C, C ++, Windows, Pascal, Fortran, Fastcall и, вероятно, еще миллион других, о которых я даже не думал упоминать. Разве одно соглашение не должно быть наиболее эффективным для подавляющего большинства вариантов использования? Есть ли когда-нибудь веская причина предпочесть одно другому?
Упомянутые вами соглашения о вызовах разрабатывались десятилетиями для разных языков и различного оборудования. У всех были разные цели. cdecl поддерживает переменные аргументы для printf. stdcall привел к уменьшению размера кода, но без переменных аргументов. Fastcall мог бы значительно ускорить выполнение простых функций всего с одним или двумя аргументами на старых машинах (но сегодня это редко ускоряет).
Обратите внимание, что когда был представлен x64, по крайней мере в Windows, он был разработан так, чтобы иметь соглашение о едином вызове.
Раймонд Чен написал отличную серию статей по истории соглашений о вызовах, вы можете начать здесь .
Дополнительная информация: http://en.wikipedia.org/wiki/X86_calling_conventions
Частично причина заключается в базовой архитектуре микропроцессора (или процессора) . Большинство языков запускаются на конкретном процессоре и немного связаны с этой архитектурой. Например, на старом компьютере серии Univac 1100 даже не было стека вызовов!
Другая часть причины заключается в том, что невозможно предугадать лучшее решение, пока вы не попробуете несколько способов сделать что-то.
Они созданы для разных целей, и с разными системами оптимизации.
Например, чтобы уменьшить "переполнение стека", (без каламбура) некоторые люди придумали различные идеи для вызова функции, чтобы сделать переполнение стека невозможным.
Другой пример - Лямбда-калькуляция. Не хочу быть слишком туманным, но в Lambda функции могут передавать только один аргумент и возвращать одно значение, и поэтому им также нужны свои собственные соглашения о вызове.
Потому что исторически каждый и их младший брат определяли свои собственные правила призвания. Все они были созданы для разных целей и, следовательно, обусловлены разными потребностями в производительности. Например, C ++ поддерживает оптимизацию для передачи параметра this
.