Це сильно характерне для операційної системи (і для комп'ютера), і на деяких ОС ви маєте кілька способів налаштувати (і навіть збільшити) ліміт. Це навіть специфічний для компілятора (або конкретний для вашої мови програмування), оскільки деякі компілятори (включаючи останні GCC для обмеженого виду коду С) здатні оптимізувати деякі хвостові дзвінки .
(деякі специфікації мови програмування вимагають оптимізації виклику, наприклад R5RS )
Я не впевнений, що ваше питання має сенс (і, звичайно, не ваша межа 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
файл (числа в байтах, в відповідно до мого 8Mb стеки межі інтуїцією, не забувайте 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
який рівень?