Czy C++ ogranicza głębokość rekurencji?

W Pythonie istnieje maksymalna głębokość rekurencji. Wygląda na to, że Python jest interpreterem, a nie kompilatorem. Czy C++ ma to samo pojęcie? Czy jest połączony tylko z limitem pamięci RAM?

Author: Narek, 2010-04-13

6 answers

Limit w C++ wynika z maksymalnego rozmiaru stosu. Zwykle jest to mniej niż rozmiar pamięci RAM o kilka rzędów wielkości, ale nadal jest dość duży. (Na szczęście duże rzeczy, takie jak string contents są zazwyczaj przechowywane nie na samym stosie.)

Limit stosu jest zazwyczaj dostrajalny na poziomie systemu operacyjnego. (Zobacz dokumenty dla wbudowanej powłoki ulimit, jeśli używasz Uniksa.) Domyślnie na tym komputerze (OSX) jest 8 MB.

[edytuj] oczywiście wielkość stosu sam w sobie nie pomaga, jeśli chodzi o ustalenie, jak głęboko możesz rekurencyjnie. Aby to wiedzieć, musisz obliczyć rozmiar rekordu aktywacji (lub rekordów) funkcji rekurencyjnej (zwanej również ramką stosu). Najprostszym sposobem na to (o którym wiem) jest użycie disassemblera (cecha większości debugerów) i odczytanie rozmiaru korekt wskaźnika stosu na początku i końcu każdej funkcji. Co jest brudne. (Można to wypracować na inne sposoby – na przykład, obliczanie różnicy między wskaźnikami do zmiennych w dwóch wywołaniach – ale są jeszcze bardziej złośliwe, zwłaszcza w przypadku przenośnego kodu. Odczyt wartości z demontażu jest łatwiejszy IMO.)

 44
Author: Donal Fellows,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-13 14:34:40

Nie, C++ nie ma wyraźnej głębi rekurencji. Jeśli maksymalny rozmiar stosu zostanie przekroczony (który domyślnie wynosi 1 MB w systemie Windows), Twój program C++ przepełni twój stos i wykonanie zostanie zakończone.

 20
Author: Justin Ethier,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-13 14:01:38

W standardach C lub c++ nie ma śledzenia głębokości rekurencji ani ograniczeń. W czasie wykonywania głębokość jest ograniczona przez to, jak duży stos może rosnąć.

 6
Author: Mike DeSimone,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-13 14:00:07

C++ ma maksymalną głębokość rekurencji, ograniczoną przez stos. Jednak nowoczesne systemy operacyjne są w stanie dynamicznie rozszerzać stos przestrzeni użytkownika w miarę jego wypełniania, ograniczając głębokość rekurencji tylko przez przestrzeń pamięci i fragmentację pamięci.

 3
Author: Ignacio Vazquez-Abrams,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-13 13:59:16

Uważam, że limitem jest wielkość stosu dostępnego na platformie. Z tego, co czytałem, jest to 8K 8MB domyślnie w Linuksie, ale nowoczesne jądra mogą dynamicznie dostosowywać rozmiar stosu.

 3
Author: Andy Shellam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-13 14:10:32

Python ma przestrajalny limit na wywołania rekurencyjne, podczas gdy C++ jest ograniczony przez rozmiar stosu.

Dodatkowo, wiele języków lub kompilatorów może zoptymalizować rekursję ogonową, usuwając ramkę stosu wywołującego, tak aby nie zużywać dodatkowej przestrzeni stosu. (W rekurencji ogonowej jedyną rzeczą, jaką robi funkcja wywołująca po wywołaniu rekurencyjnym, jest zwrócenie wartości zwracanej przez wywołanie rekurencyjne.)

int fact(int n, int accum=1){
  if (n==0) return accum;
  else return fact(n-1,n*accum); //tail recursion here.
}

Python nie optymalizuje rekurencji ogonowej (ale bez stosu Python robi), A C++ nie wymaga optymalizacji rekurencji ogonowej, ale uważam, że gcc optymalizuje rekurencję ogonową. JVM nie optymalizuje rekurencji ogonowej, chociaż język Scala robi to w pewnych typowych udokumentowanych przypadkach. Scheme i Lisp (i prawdopodobnie również inne języki funkcyjne) wymagają optymalizacji rekurencji ogonowej.

 3
Author: Ken Bloom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-13 14:14:35