Существует ли ограничение по уровню стека вызовов?

StackOverflow https://stackoverflow.com/questions/1866025

Вопрос

У меня есть пара коллег, которые просматривают какой-то плохой код в Excel VBA, задаваясь вопросом, существует ли ограничение на количество уровней в стеке вызовов

Это было полезно?

Решение

Если функция не является хвостовой рекурсивной и VBA не может ее обработать (а он не может), вы столкнетесь с переполнением стека.

В качестве простого теста я собрал следующий фрагмент:

Dim count As Integer

Sub Rec()
    count = count + 1
    Cells(1, 1) = count
    Call Rec
End Sub

это говорит нам о том, что предел для этого составляет 4007 итераций, по крайней мере, в моей версии Excel 2007 здесь.

Другие советы

короткий ответ — да, в конечном итоге вы получите исключение переполнения стека.

Хотя не знаю, какой предел.

Я только что запустил этот макрос в Excel 2003 и получил 4775 вызовов, прежде чем получил ошибку 28 «Недостаточно места в стеке»:

Sub Macro1()
    recurse (0)
End Sub

Sub recurse(level As Long)
   ActiveCell.FormulaR1C1 = Str$(level)
   Call recurse(level + 1)
End Sub

Я знаю старый вопрос, но я подумал, что было бы полезно получить актуальную информацию по этому вопросу, поскольку я изучал его сегодня.

Жесткий предел, по-видимому, составляет 6801 вызов для процедуры без параметров в Excel 2016.Как говорит VBA_interested, это число уменьшается с увеличением количества параметров рекурсивной процедуры.

Я провел следующие тесты в Excel 2016:

Sub RecurseStatic (без параметров) переполнился после 6801 рекурсии.
Sub Recurse1 (с 1 параметром) переполнился после 6442 рекурсий.
Sub Recurse2 (с двумя параметрами) переполнился после 6120.

Option Explicit

Sub RecurseStatic()
    Static i As Long
    Debug.Print i
    i = i + 1
    RecurseStatic
End Sub

Sub RunRecurse1()
    Recurse1 0
End Sub

Sub Recurse1(i As Long)
    Debug.Print i
    Recurse1 i + 1
End Sub

Sub RunRecurse2()
    Recurse2 0, 0
End Sub

Sub Recurse2(i As Long, j As Long)
    Debug.Print i, j
    Recurse2 i + 1, j + 1
End Sub

Я запустил код Андерса в Excel 2013, и результат был всего лишь 1180.Не уверен, уменьшили ли они лимит рекурсии в более новых версиях Excel, или проблема зависит от компьютера, или еще что-то в этом роде.

Редактировать:Кроме того, изменились:ActiveCell.FormulaR1C1 = Str $ (уровень) до Диапазона ("A1").FormulaR1C1 = Str $ (уровень)

И количество звонков упало до 807.Я также добавил опцию Explicit.

Потребление памяти стека.

Насколько я понимаю, стек используется для хранения параметров процедур и локальных переменных в процедурах.

Следовательно, потребление пространства стека будет пропорционально количеству рекурсивных вызовов.

Итак, необходимый размер стека примерно такой:количество рекурсивных вызовов * (размер вызываемых параметров + место для локальных переменных)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top