Переносимая функция в C (без сборки), которая возвращает размер кадра стека

Написать переносимую функцию в C (без сборки), которая возвращает размер кадра стека

int stackframe_size()
{

}

Попытка решить это, как показано ниже - Эта функция возвращает 228 байт при компиляции с VS 2010. Есть ли способ проверить ее правильность?

    int stackframe_size(int run)
    {
        int i ;

        if(!run)
        {
            return ((int)(&i) - stackframe_size(++run));

        }
        return (int)(&i);

    }

Вызывается как:

    int main()
    {
        printf("\nSize of stackframe_size() is: %d bytes",stackframe_size(0)) ;
        return 0;
    }

2 ответа

Решение

Такая портативная функция невозможна.

Ваша попытка, вероятно, примерно настолько близка, насколько вы можете получить, но вычитание указателя имеет неопределенное поведение. В более общем смысле, p1 - p0, где p0 а также p1 являются указателями на различные объекты, имеет неопределенное поведение.

За исключением того, что ваш код вычитает int значения, которые являются результатом преобразования из адресов. Прямое вычитание указателей с большей вероятностью сработает - и указатели должны быть типа char* или же unsigned char*, Есть много реализаций, где int слишком мал, чтобы содержать преобразованный указатель, а некоторые, где указатели имеют более сложное представление, чем вы предполагаете, и преобразование их в даже достаточно большой целочисленный тип не обязательно даст вам значимый результат.

Существуют реальные реализации C, которые не используют "стек" в смысле непрерывной области памяти, в которой "кадры стека" помещаются и выталкиваются. (Должен быть "стек" в смысле структуры данных "первым пришел - последним вышел", но способ реализации "стека" совершенно не определен.) Некоторые реализации мэйнфреймов IBM, например, выделяют память для функции вызов через что-то вроде кучи, так что не существует определенной связи между адресами локальных переменных для двух таких вызовов.

Вероятно, вы можете написать функцию на чистом C (без ассемблера), которая дает размер стекового фрейма для конкретной реализации. Но поскольку сам язык C не имеет понятия "стековый фрейм" (в стандарте даже не используется слово "стек"), его нельзя сделать переносимым.

Я хотел проверить, есть ли умный / более чистый способ сделать это без добавления локальных переменных

Вы могли бы использовать &run вместо &i Это спасло бы вас от локальной переменной.

Есть ли способ проверить его правильность?

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

Другие вопросы по тегам