Это сильно зависит от операционной системы (и компьютера), и в некоторых ОС у вас есть несколько способов настроить (и даже увеличить) ограничение. Это даже зависит от компилятора (или от конкретной реализации вашего языка программирования), поскольку некоторые компиляторы (включая недавний GCC для некоторого ограниченного вида кода на C) способны оптимизировать некоторые хвостовые вызовы .
(некоторые спецификации языка программирования требуют оптимизации хвостового вызова, например R5RS )
Я не уверен, что ваш вопрос имеет смысл (и, конечно, не ваш 2 16 предел). На моем рабочем столе Linux (Debian / Sid / x86-64, ядро Linux 4.9, 32 ГБ ОЗУ, Intel i5-4690S) у меня может быть стек вызовов до 8 мегабайт (и я мог бы увеличить этот предел, если бы я действительно хотел ).
Многопоточность и ASLR делает ваш вопрос гораздо сложнее . Смотрите, например, pthread_attr_setstack (3) . Читайте также о разделенных стеках (часто используемых реализациями Go ) и о стиле передачи продолжения . Смотрите также этот ответ.
Для чего это стоит, я только что попробовал следующий код C99 (а также C11):
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void recfun(int x, int d) {
printf("start recfun x=%d d=%d\n", x, d);
fflush(NULL);
if (d>0)
recfun(x+1, d-1);
printf("end recfun x=%d d=%d\n", x, d);
}
int main(int argc, char**argv) {
int md = argc>1?atoi(argv[1]):10000;
printf ("start md=%d\n", md);
recfun(0, md);
printf("end md=%d clock=%ld µs\n", md, clock());
}
// eof recur.c
и я смог запустить эту recur
программу (скомпилированную с GCC 6 as gcc -Wall -O recur.c -o recur
) recur 161000
(намного выше вашего предела в 2 16 ). С recur 256000
этим тоже работал. С recur 456000
ним разбился (с переполнением стека для уровня x=272057
). У меня нет терпения для других тестов. Попробуйте это на своем компьютере. Не забудьте спросить об оптимизации.
Эмпирическое правило (для настольных компьютеров, ноутбуков, планшетов) может заключаться в том, чтобы стек вызовов не превышал одного мегабайта.
Переходя также -fstack-usage
к gcc
получению следующего recur.su
файла (числа в байтах, в соответствии с моей интуицией ограничения стека в 8 Мбайт; не забывайте main
фрейм вызова и, что более важно, начальную компоновку стека, установленную ядром при выполнении execve (2). ) ..., для crt0 ):
recur.c:5:10:recfun 32 static
recur.c:13:9:main 16 static
PS. Мой Arduino имеет Atmega328 только с 2 Кбайт оперативной памяти, поэтому, конечно, не может повторить так много. Я предполагаю, что на Arduinos возможно практически несколько сотен фреймов стека.
here i mean by limit the maximum number of levels that can the stack have
какой уровень?