Ваш второй пример также не является примером рекурсии. Это всего лишь пример того, что я бы неофициально назвал «связанными вызовами подпрограмм» - я не верю, что есть формальный термин для этого. Рекурсия требует, чтобы подпрограмма вызывала сама себя либо напрямую, либо через некоторый набор посредников.
Например, если подпрограмма D имеет вызов A, B или C при определенных условиях, это будет рекурсия.
Что касается глубоких стеков вызовов, ответ зависит от:
- как глубоко
- сколько аргументов вы передаете в каждом
- сколько памяти может выделить ваша программа
Каждый раз, когда вы вызываете подпрограмму, она добавляет новый кадр в стек вызовов. Этот кадр остается до завершения подпрограммы. Размер этого стекового фрейма зависит в первую очередь от длины вашего списка аргументов плюс некоторые фиксированные накладные расходы.
Так что в этом случае у вас будет стековый фрейм с четырьмя элементами.
Если ваша цепочка вызовов становится слишком глубокой и каждая запись имеет длинный список аргументов, вам в конечном итоге не хватит места для стека вызовов. Это называется переполнением стека. :)