È fortemente specifico del sistema operativo (e specifico del computer) e su alcuni sistemi operativi hai alcuni modi per configurare (e persino aumentare) il limite. È persino specifico del compilatore (o specifico del tuo linguaggio di programmazione), dal momento che alcuni compilatori (incluso GCC recente per qualche tipo limitato di codice C) sono in grado di ottimizzare alcune chiamate di coda .
(alcune specifiche del linguaggio di programmazione richiedono ottimizzazioni delle chiamate di coda, ad es. R5RS )
Non sono sicuro che la tua domanda abbia un senso (e certamente non il tuo limite di 2 16 ). Sul mio desktop Linux (Debian / Sid / x86-64, kernel Linux 4.9, RAM 32Gb, Intel i5-4690S), potrei avere uno stack di chiamate fino a 8 megabyte (e potrei aumentare quel limite, se volessi davvero ).
Il multi-threading e ASLR stanno rendendo la tua domanda molto più complessa . Vedi ad esempio pthread_attr_setstack (3) . Leggi anche informazioni sugli stack divisi (spesso utilizzati dalle implementazioni Go ) e sullo stile del passaggio di continuazione . Vedi anche questa risposta.
Per quello che vale, ho appena provato il seguente codice C99 (e anche 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
e sono stato in grado di eseguire quel recur
programma (compilato con GCC 6 as gcc -Wall -O recur.c -o recur
) come recur 161000
(molto al di sopra del limite di 2 16 ). Con recur 256000
ha anche funzionato. Con recur 456000
esso si è schiantato (con un overflow dello stack per livello x=272057
). Non ho la pazienza per altri test. Provalo sul tuo computer. Non dimenticare di chiedere ottimizzazioni.
Una regola empirica (per desktop, laptop, tablet) potrebbe essere quella di mantenere lo stack delle chiamate al di sotto di un megabyte.
Passando anche -fstack-usage
a gcc
sto ottenendo il seguente recur.su
file (i numeri sono in byte, coerenti con la mia intuizione del limite dello stack da 8 Mb; non dimenticare il main
frame di chiamata e, soprattutto, il layout dello stack iniziale, installato dal kernel quando si esegue execve (2 ) ..., per crt0 ):
recur.c:5:10:recfun 32 static
recur.c:13:9:main 16 static
PS. Il mio Arduino ha un Atmega328 con solo 2Kbyte di RAM, quindi sicuramente non può ricorrere così tanto. Immagino che solo poche centinaia di frame stack siano praticamente possibili su Arduinos.
here i mean by limit the maximum number of levels that can the stack have
qual è il livello?