Это все очень специфично для Windows, мы не говорим здесь о стандартном C ++.
Извлекая документацию StartServiceDispatcher
, она имеет только один аргумент и объявлена какWINAPI
что в свою очередь означает __stcall
соглашение о вызовах.
Для автономных функций __stdcall
является одним из двух основных соглашений о вызовах.Другой - __cdecl
.Разница в уровне машинного кода заключается в том, кто просто восстанавливает указатель стека: с __stdcall
это сама функция, а с __cdecl
это код вызова.
Когда функция на самом деле __stdcall
, новызывается так, как если бы это было __cdecl
, ситуация в том, что существует две попытки восстановить указатель стека: одна на выходе из функции и одна в вызывающем коде.Тот, что в функции, будет успешным.В зависимости от того, как выполняется попытка в вызывающем коде, он может полностью испортить ситуацию (например, если просто добавить требуемое смещение, относиться к указателю стека как относительному), или он может не оказать вредного влияния.Но, скорее всего, это создаст беспорядок, поскольку предположение о значении указателя стека при возврате из функции неверно.
Когда функция на самом деле равна __cdecl
, она сама не будет восстанавливать указатель стека, посколькуэто ответственность вызывающего кода.И если вызывающий код рассматривает его как __stdcall
, то вызывающий код также не восстановит его, так как с точки зрения вызывающего кода функция делает это.В результате, если вы не получите преждевременный сбой (из-за неправильных предположений), должно получиться так, что повторные вызовы, скажем, в цикле, будут использовать пространство стека.
Это все очень неопределенное поведение.
И одно свойство Неопределенного поведения - то, что он может делать все что угодно, в том числе, очевидно, работающий…
Приветствия & hth.,