Je suppose que vous comprenez que les deux fonctions se bloquent en raison de l'épuisement de la pile après une tentative de récursion infinie. Je pense que ce que vous demandez est: pourquoi l'exemple de cout ne plante pas avec "Stack Overflow" aussi?
Je ne pense pas que la réponse a à voir avec la détection par le compilateur de la récurrence de la queue. Si le compilateur a optimisé la récursivité, aucun exemple ne doit tomber en panne.
J'ai une idée de ce qui se passe. L'exception "Stack Overflow" est implémentée dans certains cas (par exemple, Windows) avec une "page de garde" de mémoire virtuelle unique allouée à la fin de la pile. Lorsqu'un accès de pile frappe cette page de garde, un type d'exception spécial est généré.
Étant donné que la page de petite granularité d'Intel a une longueur de 4096 octets, la page de garde veille sur une plage de mémoire de cette taille. Si un appel de fonction alloue plus de 4096 octets de variables locales, il est possible que le premier accès de la pile s'étende réellement à au-delà de la page de garde. La page suivante peut être supposée être de la mémoire non réservée, donc une violation d'accès aurait du sens dans ce cas.
Bien sûr, vous ne déclarez explicitement aucune variable locale dans votre exemple. Je suppose que l'un des opérateurs < <() méthodes alloue plus d'une page de variables locales. En d'autres termes, que la violation d'accès se produit au début d'un opérateur < <() méthode ou une autre partie de l'implémentation de cout (constructeurs d'objets temporaires, etc.)
Aussi, même dans la fonction que vous avez écrite, le opérateur < <() les implémentations vont avoir besoin de créer du stockage pour les résultats intermédiaires. Ce stockage est probablement alloué en tant que stockage local par le compilateur. Je doute que cela puisse ajouter jusqu'à 4k dans votre exemple, cependant. La seule façon de vraiment comprendre serait de voir une trace de pile de la violation d'accès pour voir quelle instruction la déclenche.Vous avez une trace de pile de la violation d'accès et un désassemblage autour de la zone de l'opcode fautif?
Si vous utilisez le compilateur Microsoft C, une autre possibilité est que printf() et votre propre fonction ont été compilés avec/Ge et l'opérateur < <() ne l'était pas, ou que seule votre fonction a été compilée avec/Ge et ses facteurs semblables à ceux décrits ci-dessus provoquent par hasard le comportement que vous voyez - parce que dans l'exemple printf() l'accident se produit pendant que votre fonction est appelée et dans l'opérateur < <() cas pendant que vous appelez la bibliothèque.
Avez-vous inclus les fichiers d'en-tête corrects? – Toad
Hmmm ... vous demandez pourquoi le premier exemple donne une violation d'accès au lieu d'un débordement de pile et en réponse tout le monde vous dit pourquoi le second exemple donne un débordement de pile. Intéressant comment tout le monde répond à la question perçue qu'ils connaissent la réponse à la place de la question que vous demandez réellement. –
D'accord avec Paul. –