Среда выполнения может обнаружить дисбаланс стека, потому что указатель стека не там, где он ожидается. То есть в случае StdCall
, где ожидаемая функция должна очистить стек, среда выполнения могла бы сделать это:
SavedSP = SP; // save the stack pointer
// now push parameters
// call the external function.
if (SP != SavedSP)
{
// error!
}
Теперь, если значение SP
меньше, чем SavedSP
, в стеке есть дополнительные данные - это означает, что среда выполнения может просто продолжить и восстановить сохраненный указатель стека.
Среда выполнения всегда должна обнаруживать дисбаланс в стеке. Могу ли я всегда выздоравливать, мне неизвестно. Но в случае непреднамеренного вызова метода Cdecl
как StdCall
он должен быть в состоянии восстановиться без проблем, так как в стеке будет дополнительный материал, который он может игнорировать.
А зачем? Как вы говорите, разница между StdCall
и Cdecl
заключается только в том, кто отвечает за очистку стека. Кроме того, StdCall
не совместим со списками переменных аргументов (т.е. printf
в C), хотя я не знаю, возможно ли вообще вызывать такой метод из .NET (никогда не было необходимости). В любом случае, хотя не возникает особой проблемы с вызовом Cdecl
метода с StdCall
, мне нравится знать, что существует потенциальная ошибка. Для меня это похоже на сообщение об ошибке, которое выдает компилятор, когда вы пишете:
uint x = 3;
int y = x; // error!
Я знаю, что с назначением все в порядке, но компилятор запрещает его, потому что это потенциальный источник ошибок. На мой взгляд, несбалансированный стек является потенциальным источником ошибок. Нет, это - это ошибка, которая может вызвать некоторые очень плохие вещи. Я бы предпочел, чтобы среда выполнения сказала мне об этом, чтобы я мог решить проблему.