0
votes

Main récursivement appelé sans variables locales

Quelle est la sortie des éléments suivants: xxx

options:

  1. Main est appelé Infinite Times
  2. Main est appelé 65535 fois.
  3. Main est appelé 32765 fois.
  4. Overflow de pile.
  5. Erreur de compilation.

    Mon analyse: Je pense que l'option 1. Aussi correcte. Option 2,3 et 5 définitivement pas. Je ne pense pas aussi pour l'option 4 aussi. Raison, je crois que le débordement de la pile aurait pu se produire, si la fonction principale utilisait certaines variables locales consommant une mémoire. Donc, je pense que l'option 1 est correcte! Je suis d'accord, la fonction récursive provoque le débordement de la pile, mais cela dépend également de ce que les fonctions implémentent. Dans ce cas, seul printf est imprimé. S'il vous plaît laissez-moi savoir vos commentaires à ce sujet. Merci!

c

6 commentaires

Avez-vous essayé de compiler et d'exécuter le code pour savoir ce qui se passe?


Si vous essayez dans CodePad.org, il court infinistement jusqu'à ce que le délai d'attente se produise. Je n'ai pas essayé d'un environnement matériel.


Le cadre de pile est si petit qu'il pourrait ne pas trop déborder avant que le délai d'attente ne se produise.


Ou, la compilez et lisez la sortie de l'assemblage. Par exemple. goodbolt.org/z/q3frg1 . Sans optimisations, vous verrez un instructions principales , qui appuitent implicitement l'adresse de retour actuelle sur la pile. Donc, la pile pousse avec chaque appel et finira par déborder.


principal ne doit pas être récursif


@BasileStarynkevitch tandis que c'est généralement une mauvaise idée, je pense que cela le permet (mais C ++ ne le fait pas, et je ne connais pas d'autres dialectes C). Mais quelque chose à propos de cette question est-il vraiment spécifique à principal () ? La question serait la même avec toute autre fonction qui n'a pas de paramètres ni de variables locales.


3 Réponses :


3
votes

Ceci est dépendant de la mise en œuvre. La langue ne dit rien de la manière dont les appels de fonction sont mis en œuvre, ils doivent simplement produire les résultats corrects pour les programmes valides.

Dans la plupart des implémentations, je m'attendais à # 4. Même si vous n'avez pas de variables locales, il a toujours besoin d'un cadre de pile pour maintenir l'emplacement de retour.

Si votre fonction était récursive de la queue et que le compilateur optimise les appels de la queue, vous éviteriez la pile débordement. . Pour que cela fonctionne, la fonction devrait se terminer par: xxx


3 commentaires

Mais cela n'atteint pas la déclaration de retour.


Si le compilateur pouvait comprendre cela, il aurait probablement averti que retour est inaccessible. Donc, il compilait probablement la fonction comme si principal () pourrait revenir et il doit sauvegarder l'état.


En réalité, cette définition est tce-capable, comme: le compilateur peut voir que la valeur de retour de l'appel récursif n'est pas utilisée et que le rendement syntaxique ne dépend pas de celui-ci, donc aucune pile n'a besoin d'être maintenue à l'externe (qui implicitement retourne 0 simplement parce que c'est principal ). Mais TCE est fragile en C même dans les compilateurs qui prétendent le soutenir.



0
votes

Ignorer un instant qui appelant de manière récursive principale n'est pas une bonne idée, vous vous retrouverez avec un débordement de pile si vous exécutez ce code.

Même sans variables locales, la pile doit toujours garder une trace de l'adresse de retour de la fonction. Cette adresse de retour s'ajoutera et finira par faire sauter la pile.



-1
votes

Ce sera la première erreur de compilation dans votre cas en tant que fonction du type de retour Int ne renvoie aucune valeur.

Il existe également un cas de débordement de pile comme chaque fois que le principal () est appelé Stack stocke l'adresse de l'instruction de retour qui doit être exécutée après la principale que dans votre case ne se produit pas et ne fonctionne plus à nouveau.

Ainsi, après chaque pile d'appels aura l'adresse de la déclaration de retour.


0 commentaires