Es ist stark betriebssystemspezifisch (und rechnerspezifisch) und unter einigen Betriebssystemen haben Sie einige Möglichkeiten, das Limit zu konfigurieren (und sogar zu erhöhen). Es ist sogar compilerspezifisch (oder spezifisch für Ihre Programmiersprachenimplementierung), da einige Compiler (einschließlich des aktuellen GCC für eine begrenzte Art von C-Code) einige Tail-Aufrufe optimieren können .
(Einige Programmiersprachen-Spezifikationen erfordern Tail-Call-Optimierungen, z. B. R5RS. )
Ich bin mir nicht sicher, ob Ihre Frage Sinn macht (und schon gar nicht Ihr 2 16- Limit). Auf meinem Linux-Desktop (Debian / Sid / x86-64, Linux 4.9-Kernel, 32 GB RAM, Intel i5-4690S) habe ich möglicherweise einen Aufrufstapel von bis zu 8 Megabyte (und ich könnte dieses Limit erhöhen, wenn ich es wirklich wollte ).
Multithreading und ASLR machen Ihre Frage viel komplexer . Siehe z. B. pthread_attr_setstack (3) . Lesen Sie auch über Split-Stacks (häufig von Go- Implementierungen verwendet) und über den Continuation-Passing-Stil . Siehe auch diese Antwort.
Für das, was es wert ist, habe ich gerade den folgenden C99 (und auch C11) Code ausprobiert:
#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
und ich konnte dieses recur
Programm (kompiliert mit GCC 6 as gcc -Wall -O recur.c -o recur
) ausführen recur 161000
(so weit über Ihrem 2 16- Limit). Damit hat recur 256000
es auch geklappt. Damit recur 456000
stürzte es ab (mit einem Stapelüberlauf für Level x=272057
). Ich habe nicht die Geduld für andere Tests. Versuchen Sie das auf Ihrem Computer. Vergessen Sie nicht, nach Optimierungen zu fragen.
Als Faustregel (für Desktops, Laptops, Tablets) gilt möglicherweise, dass Ihr Anrufstapel unter einem Megabyte liegt.
Wenn ich auch -fstack-usage
an übergebe , erhalte gcc
ich die folgende recur.su
Datei (Zahlen sind in Bytes, was mit meiner 8-MB-Stapelbegrenzungsintuition übereinstimmt; vergessen Sie nicht den Aufrufrahmen main
und vor allem das anfängliche Stapellayout, das der Kernel beim Ausführen installiert hat (2) ) ..., für crt0 ):
recur.c:5:10:recfun 32 static
recur.c:13:9:main 16 static
PS. Mein Arduino hat einen Atmega328 mit nur 2 KB RAM, kann also sicher nicht so viel wiederholen. Ich denke, auf Arduinos sind höchstens ein paar Hundert Stack-Frames praktisch möglich.
here i mean by limit the maximum number of levels that can the stack have
Was ist ein Level?