web-dev-qa-db-fra.com

C ++ limite-t-il la profondeur de récursivité?

Dans Python il y a une profondeur de récursivité maximale. Semble que c'est parce que Python est un interpréteur, pas un compilateur. C++ a-t-il le même concept? Ou c'est connecté uniquement avec RAM limit?

55
Narek

La limite en C++ est due à la taille maximale de la pile. C'est généralement inférieur à la taille de RAM de plusieurs ordres de grandeur, mais est toujours assez grand. (Heureusement, de grandes choses comme la chaîne conten sont généralement détenues non sur la pile elle-même.)

La limite de pile est généralement réglable au niveau du système d'exploitation. (Voir la documentation de ulimit Shell intégré si vous êtes sous Unix.) La valeur par défaut sur cette machine (OSX) est de 8 Mo.

[EDIT] Bien sûr, la taille de la pile n'aide pas tout à fait d'elle-même quand il s'agit de déterminer la profondeur à laquelle vous pouvez recurer. Pour le savoir, vous devez calculer la taille de enregistrement d'activation (ou enregistrements) de la fonction récursive (également appelée trame de pile). La façon la plus simple de le faire (à ma connaissance) est d'utiliser un désassembleur (une caractéristique de la plupart des débogueurs) et de lire la taille des ajustements du pointeur de pile au début et à la fin de chaque fonction. Ce qui est désordonné. (Vous pouvez trouver d'autres moyens - par exemple, calculer la différence entre les pointeurs vers les variables en deux appels - mais ils sont encore plus méchants, en particulier pour le code portable. La lecture des valeurs hors du démontage est plus facile IMO.)

47
Donal Fellows

Non, C++ n'a pas de profondeur de récursivité explicite. Si la taille maximale de la pile est dépassée (qui est de 1 Mo par défaut sous Windows), votre programme C++ débordera votre pile et l'exécution sera interrompue.

22
Justin Ethier

Il n'y a pas de suivi de profondeur de récursivité ni de limite dans les normes C ou C++. Au moment de l'exécution, la profondeur est limitée par la taille de la pile.

6
Mike DeSimone

Python a un limite réglable sur les appels récursifs, tandis que C++ est limité par la taille de la pile.

De plus, de nombreux langages ou compilateurs peuvent optimiser la récursivité de la queue en supprimant le cadre de pile de l'appelant afin qu'aucun espace de pile supplémentaire ne soit consommé. (Dans la récursivité de queue, la seule chose que la fonction appelante fait après avoir effectué l'appel récursif est de renvoyer la valeur de retour de l'appel récursif.)

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

Python n'optimise pas la récursivité de queue (mais Python sans pile le fait), et C++ ne nécessite pas d'optimisation de récursivité de queue, mais je crois que gcc optimise la récursivité de queue. La JVM n'optimise pas la récursivité de queue, bien que le langage Scala le fasse dans certains cas documentés courants. Le schéma et LISP (et probablement d'autres langages fonctionnels également) nécessitent que la récursivité de queue soit optimisée.

3
Ken Bloom

C++ a une profondeur de récursivité maximale, limitée par la pile. Cependant, les systèmes d'exploitation modernes peuvent étendre dynamiquement une pile d'espace utilisateur au fur et à mesure qu'elle se remplit, limitant la profondeur de récursivité uniquement par l'espace mémoire et la fragmentation de la mémoire.

3

Je crois que la limite est la taille de la pile disponible sur la plate-forme. D'après ce que j'ai lu, c'est 8K 8 Mo par défaut sous Linux, mais les noyaux modernes peuvent ajuster dynamiquement la taille de la pile.

3
Andy Shellam