Pourquoi les compilateurs n'insèrent-ils pas automatiquement les désallocations?

63

Dans des langages tels que C, le programmeur est censé insérer des appels pour libérer. Pourquoi le compilateur ne le fait-il pas automatiquement? Les humains le font dans un délai raisonnable (en ignorant les bugs), donc ce n'est pas impossible.

EDIT: Pour une référence future, voici une autre discussion qui présente un exemple intéressant.

Milton Silva
la source
125
Et c’est pour cela que nous vous enseignons la théorie de la calculabilité. ;)
Raphael
7
Ce n'est pas un problème de calcul car les humains ne peuvent pas décider dans tous les cas non plus. C'est un problème de complétude; Les instructions de désallocation contiennent des informations qui, si elles sont supprimées, ne peuvent pas être entièrement récupérées par l'analyse, à moins que cette analyse ne contienne des informations sur l'environnement de déploiement et le fonctionnement attendu, que le code source C ne contient pas.
Nat
41
Non, c'est un problème de calcul. Il est indécidable de savoir si un morceau de mémoire donné doit être désalloué. Pour un programme fixe, aucune entrée utilisateur ou autre interférence externe.
Andrej Bauer
1
Les commentaires ne sont pas pour une discussion prolongée; cette conversation a été déplacée pour discuter . Tous les commentaires qui ne traitent pas spécifiquement de la question et de la manière de l'améliorer seront supprimés à vue.
Raphaël
2
@ BorisTreukhov, s'il vous plaît apportez-le à la salle de discussion. Non, je ne pense pas qu'Andrej dise que l'analyse de fuite est "impossible" (bien que déterminer exactement ce que cela signifie dans ce contexte est un peu flou pour moi). Une analyse d'évacuation parfaitement précise est indécidable. À tous: s'il vous plaît, amenez-le au salon de discussion . Publiez ici uniquement les commentaires visant à améliorer la question. Les autres discussions et commentaires doivent être postés dans le salon de discussion.
DW

Réponses:

81

Parce qu'il est indécidable que le programme utilise à nouveau la mémoire. Cela signifie qu'aucun algorithme ne peut déterminer correctement le moment d'appeler free()dans tous les cas, ce qui signifie qu'un compilateur qui aurait tenté de le faire produirait nécessairement certains programmes avec des fuites de mémoire et / ou des programmes continuant à utiliser la mémoire libérée. Même si vous vous êtes assuré que votre compilateur n'a jamais fait le deuxième et que le programmeur insère des appels pour free()corriger ces bogues, il free()serait encore plus difficile de savoir quand appeler ce compilateur. Savoir quand appeler free()lorsque vous utilisez un compilateur qui n'a pas essayé aider.

David Richerby
la source
12
Nous avons une question qui couvre la capacité des humains à résoudre des problèmes indécidables . Je ne peux pas vous donner un exemple de programme mal compilé car cela dépend de l'algorithme utilisé par le compilateur. Mais tout algorithme produira une sortie incorrecte pour une infinité de programmes différents.
David Richerby
1
Les commentaires ne sont pas pour une discussion prolongée; cette conversation a été déplacée pour discuter .
Gilles 'SO- arrête d'être méchant' le
2
Les gars, prenez-le pour discuter . Tout ce qui ne se rapporte pas directement à la réponse et à la façon de l'améliorer sera supprimé.
Raphaël
2
Beaucoup de choses que les compilateurs font heureusement sont indécidables en général; nous n'aurions rien dans le monde du compilateur si nous avions toujours cédé au théorème de Rice.
Tikhon Jelvis
3
Ceci n'est pas pertinent. Si c'est indécidable pour tous les compilateurs, c'est également indécidable pour tous les humains. Pourtant, nous attendons des humains qu'ils s'insèrent free()correctement.
Paul Draper
53

Comme David Richerby l’a noté à juste titre, le problème est indécidable en général. La qualité de l'objet est une propriété globale du programme et peut en général dépendre des entrées du programme.

Même le ramassage des ordures dynamique et précis est un problème indécidable! Tous les éboueurs du monde réel utilisent l'accessibilité comme une approximation prudente pour déterminer si un objet attribué sera nécessaire ou non à l'avenir. C'est une bonne approximation, mais c'est quand même une approximation.

Mais ce n'est que vrai en général. L'un des problèmes les plus notoires dans le secteur de l'informatique est "c'est impossible en général, donc nous ne pouvons rien faire". Au contraire, il existe de nombreux cas où il est possible de progresser.

Les implémentations basées sur le comptage de références sont très proches de "le compilateur insérant des désallocations", de sorte qu'il est difficile de faire la différence. Le comptage automatique des références de LLVM (utilisé dans Objective-C et Swift ) est un exemple célèbre.

L'inférence de région et la récupération de place au moment de la compilation sont des domaines de recherche actifs. Cela s'avère beaucoup plus facile dans les langages déclaratifs tels que ML et Mercury , dans lesquels vous ne pouvez pas modifier un objet après sa création.

Maintenant, en ce qui concerne les humains, il existe trois manières principales pour les humains de gérer manuellement les durées de vie des allocations:

  1. En comprenant le programme et le problème. Les humains peuvent placer des objets ayant une durée de vie similaire dans le même objet d'allocation, par exemple. Les compilateurs et les éboueurs doivent en déduire, mais les humains ont des informations plus précises.
  2. En utilisant sélectivement la comptabilité non locale (par exemple, comptage de références) ou d'autres techniques d'allocation spéciales (par exemple, des zones) uniquement lorsque cela est nécessaire. Encore une fois, un humain peut savoir ceci lorsqu'un compilateur doit l'inférer.
  3. Mal. Tout le monde connaît les programmes déployés dans le monde réel qui ont des fuites lentes, après tout. Sinon, les programmes et les API internes doivent parfois être restructurés en fonction de la durée de vie de la mémoire, ce qui réduit la réutilisabilité et la modularité.
Pseudonyme
la source
Les commentaires ne sont pas pour une discussion prolongée. Si vous souhaitez discuter entre déclaratif et fonctionnel, veuillez le faire en chat .
Gilles 'SO- arrête d'être méchant'
2
C'est de loin la meilleure réponse à la question (que trop de réponses n'abordent même pas). Vous auriez pu ajouter une référence au travail pionnier de Hans Boehm sur le conservateur GC : en.wikipedia.org/wiki/Boehm_garbage_collector . Un autre point intéressant est que la vivacité des données (ou l'utilité dans un sens étendu) peut être définie par rapport à une sémantique abstraite ou à un modèle d'exécution. Mais le sujet est vraiment vaste.
Babou
29

C'est un problème d'inachèvement, pas un problème d'indécidabilité

S'il est vrai que le placement optimal des déclarations de désallocation est indécidable, ce n'est tout simplement pas le problème ici. Comme il est indécidable à la fois pour les humains et les compilateurs, il est impossible de toujours choisir en connaissance de cause le placement optimal de la désallocation, qu'il s'agisse d'un processus manuel ou automatique. Et comme personne n'est parfait, un compilateur suffisamment avancé devrait être en mesure de surpasser les performances humaines en devinant les emplacements approximativement optimaux. L’ indécidabilité n’est donc pas la raison pour laquelle nous avons besoin d’énoncés explicites de désallocation .

Il existe des cas dans lesquels des connaissances externes informent le placement des instructions de désallocation. Supprimer ces instructions équivaut alors à supprimer une partie de la logique opérationnelle. Demander à un compilateur de générer automatiquement cette logique revient à lui demander de deviner ce que vous pensez.

Par exemple, supposons que vous écrivez une boucle Read-Evaluate-Print-Loop (REPL) : l'utilisateur tape une commande et votre programme l'exécute. L'utilisateur peut allouer / désallouer de la mémoire en tapant des commandes dans votre REPL. Votre code source spécifierait ce que le REPL doit faire pour chaque commande utilisateur possible, y compris la désaffectation lorsque l'utilisateur tape la commande correspondante.

Mais si le code source C ne fournit pas de commande explicite pour désallocation, le compilateur devra en déduire qu’il doit effectuer le dellocation lorsque l’utilisateur entre la commande appropriée dans le REPL. Cette commande est-elle "désallouer", "libre" ou autre chose? Le compilateur n'a aucun moyen de savoir ce que vous voulez que la commande soit. Même si vous programmez en logique la recherche de ce mot de commande et que le REPL le trouve, le compilateur n'a aucun moyen de savoir qu'il devrait y répondre par une désallocation, à moins que vous ne le lui indiquiez explicitement dans le code source.

tl; dr Le problème est que le code source C ne fournit pas au compilateur des connaissances externes. Le problème n’est pas l’indécidabilité, qu’il s’agisse d’un processus manuel ou automatisé.

Nat
la source
3
Les commentaires ne sont pas pour une discussion prolongée; cette conversation a été déplacée pour discuter . Tous les autres commentaires qui ne traitent pas spécifiquement des lacunes de cette réponse et de la façon dont ils peuvent être corrigés seront supprimés à vue.
Raphaël
23

Actuellement, aucune des réponses postées n'est totalement correcte.

Pourquoi les compilateurs n'insèrent-ils pas automatiquement les désallocations?

  1. Certains le font. (Je vais expliquer plus tard.)

  2. Essentiellement, vous pouvez appeler free()juste avant la fin du programme. Mais votre question implique implicitement que votre question appelle free()dès que possible.

  3. Le problème de savoir quand appeler free()un programme en C dès que la mémoire est inaccessible est indécidable, c'est-à-dire que pour tout algorithme fournissant la réponse en temps fini, il existe un cas qu'il ne couvre pas. Ceci, et de nombreuses autres indécidabilités de programmes arbitraires, peut être prouvé par le problème Halting .

  4. Un problème indécidable ne peut pas toujours être résolu en temps fini par un algorithme, qu'il s'agisse d'un compilateur ou d'un humain.

  5. Les humains (tentent de) écrire dans un sous - ensemble de programmes C dont l’ exactitude de la mémoire peut être vérifiée par leur algorithme (eux-mêmes).

  6. Certaines langues accomplissent le n ° 1 en intégrant le n ° 5 dans le compilateur. Ils n'autorisent pas les programmes avec des utilisations arbitraires d'allocation de mémoire, mais plutôt un sous-ensemble décidable d'entre eux. Foth et Rust sont deux exemples de langages ayant une allocation de mémoire plus restrictive que les C malloc(), qui peuvent (1) détecter si un programme est écrit en dehors de leur ensemble décidable (2) insérer automatiquement des désallocations.

Paul Draper
la source
1
Je comprends comment Rust le fait. Mais je n'ai jamais entendu parler d'un Forth qui a fait cela. Peux-tu élaborer?
Milton Silva
2
@MiltonSilva, Forth - du moins sa mise en œuvre la plus fondamentale et la plus originale - n'a qu'un empilement, pas un tas. Cela rend l'allocation / désallocation déplacer le pointeur de la pile d'appels, une tâche que le compilateur peut facilement effectuer. Forth a été conçu pour cibler du matériel très simple, et parfois une mémoire non dynamique est tout ce qui est réalisable. Ce n'est évidemment pas une solution viable pour des programmes non triviaux.
Paul Draper
10

"Les humains le font, alors ce n'est pas impossible" est une erreur bien connue. Nous ne comprenons pas nécessairement (et encore moins contrôlons) les choses que nous créons - la monnaie est un exemple courant. Nous avons tendance à surestimer (parfois considérablement) nos chances de succès en matière de technologie, en particulier lorsque les facteurs humains semblent être absents.

Les performances humaines en programmation informatique sont très médiocres et l’étude de l’informatique (qui manque dans de nombreux programmes de formation professionnelle) permet de comprendre pourquoi ce problème n’a pas une solution simple. Nous pourrions un jour, peut-être pas trop loin, être remplacés par une intelligence artificielle au travail. Même dans ce cas, il n’y aura pas d’algorithme général permettant de désallouer correctement, automatiquement, à tout moment.

André Souza Lemos
la source
1
L'erreur consistant à accepter le principe de la faillibilité humaine et à supposer que des machines pensantes créées par l'homme peuvent toujours être infaillibles (c'est-à-dire meilleures que les humains) est moins connue mais plus intriguante. La seule hypothèse à partir de laquelle on peut agir est que l'esprit humain a le potentiel de calculer parfaitement.
Wildcard
1. Je n'ai jamais dit que les machines à penser pouvaient être infaillibles. Mieux que les humains sont ce qu'ils sont déjà, dans de nombreux cas. 2. L'attente de la perfection (même potentielle) comme condition préalable à l'action est une absurdité.
André Souza Lemos
"Nous pourrions un jour, peut-être pas trop loin, être remplacés par une intelligence artificielle au travail." Ceci, en particulier, est un non-sens. Les humains sont la source d'intention du système. Sans l'homme, le système n'a pas de raison d' être. L '"intelligence artificielle" pourrait être définie comme l' apparence d'une décision intelligente du moment présent prise par des machines, provoquée en fait par les décisions intelligentes d'un programmeur ou d'un concepteur de système dans le passé. S'il n'y a pas de maintenance (qui doit être effectuée par une personne), l'IA (ou tout système non contrôlé et entièrement automatique) échouera.
Wildcard
L'intention, chez l'homme comme dans la machine, vient toujours de l' extérieur .
André Souza Lemos
Totalement faux. (Et aussi, "extérieur" ne définit pas une source. ) Soit vous déclarez que l'intention en tant que telle n'existe pas réellement, ou vous déclarez que l'intention existe mais ne vient pas de nulle part. Vous pensez peut-être que l'intention peut exister indépendamment de l'intention? Dans ce cas, vous comprenez mal le mot "intention". Quoi qu'il en soit, une démonstration en personne changera bientôt votre avis sur ce sujet. Je laisserai tomber après ce commentaire car les mots seuls ne peuvent pas amener à une compréhension de «l'intention», de sorte qu'une discussion plus poussée ici est inutile.
Wildcard
9

L'absence de gestion automatique de la mémoire est une caractéristique du langage.

C n'est pas censé être un outil pour écrire un logiciel facilement. C'est un outil permettant à l'ordinateur de faire ce que vous lui dites. Cela inclut l’allocation et la désallocation de la mémoire au moment de votre choix. C est un langage de bas niveau que vous utilisez lorsque vous souhaitez contrôler l'ordinateur avec précision ou lorsque vous souhaitez effectuer des tâches d'une manière différente de celle attendue par les concepteurs de bibliothèques de langage / standard.

Jouni Sirén
la source
Les commentaires ne sont pas pour une discussion prolongée; cette conversation a été déplacée pour discuter .
DW
2
En quoi est-ce une réponse à la (partie CS de la) question?
Raphaël
6
@ Raphaël L'informatique ne signifie pas qu'il faille chercher des réponses techniques obscures. Les compilateurs font beaucoup de choses impossibles dans le cas général. Si nous voulons une gestion automatique de la mémoire, nous pouvons l’implémenter de différentes manières. C ne le fait pas, parce que ce n'est pas censé le faire.
Jouni Sirén
9

Le problème est principalement un artefact historique, pas une impossibilité de mise en œuvre.

Le code de construction de la plupart des compilateurs C est tel que le compilateur ne voit que chaque fichier source à la fois; il ne voit jamais tout le programme à la fois. Lorsqu'un fichier source appelle une fonction à partir d'un autre fichier source ou d'une bibliothèque, le compilateur voit uniquement le fichier d'en-tête avec le type de retour de la fonction, pas le code réel de la fonction. Cela signifie que lorsqu'une fonction renvoie un pointeur, le compilateur n'a aucun moyen de savoir si la mémoire sur laquelle le pointeur pointe doit être libérée ou non. L'information à décider qui n'est pas montrée au compilateur à ce moment-là. De son côté, un programmeur humain est libre de rechercher le code source de la fonction ou la documentation pour savoir ce qu’il faut faire avec le pointeur.

Si vous examinez des langages de bas niveau plus modernes tels que C ++ 11 ou Rust, vous constaterez qu'ils résolvent principalement le problème en rendant la propriété de la mémoire explicite dans le type du pointeur. En C ++, vous utiliseriez un à la unique_ptr<T>place d'un simple T*pour conserver la mémoire et la unique_ptr<T>vérifie que la mémoire est libérée lorsque l'objet atteint la fin de la portée, contrairement à l'objet ordinaire T*. Le programmeur peut transmettre la mémoire de l'un unique_ptr<T>à l'autre, mais il ne peut jamais y en avoir qu'un qui unique_ptr<T>pointe vers la mémoire. Il est donc toujours clair à qui appartient la mémoire et quand elle doit être libérée.

Le C ++, pour des raisons de compatibilité ascendante, permet toujours la gestion manuelle de la mémoire à l’ancien style et donc la création de bogues ou de moyens de contourner la protection d’un unique_ptr<T>. Rust est encore plus strict dans la mesure où il applique des règles de propriété de la mémoire via les erreurs du compilateur.

En ce qui concerne l’indécidabilité, le problème d’arrêt, etc., oui, si vous vous en tenez à la sémantique C, il n’est pas possible de décider pour tous les programmes quand la mémoire doit être libérée. Cependant, pour la plupart des programmes actuels, et non des exercices académiques ou des logiciels bogués, il serait absolument possible de décider quand libérer ou non. Après tout, c’est la seule raison pour laquelle l’homme peut déterminer quand libérer ou non.

Grumbel
la source
Les commentaires ne sont pas pour une discussion prolongée; cette conversation a été déplacée pour discuter .
Raphaël
6

D'autres réponses ont porté sur la possibilité de procéder à la collecte des ordures, sur certains détails de la procédure et sur certains problèmes.

Un problème qui n’a pas encore été couvert est le retard inévitable dans le ramassage des ordures. En C, quand un programmeur appelle free (), cette mémoire est immédiatement disponible pour une réutilisation. (En théorie du moins!) Ainsi, un programmeur peut libérer sa structure de 100 Mo, allouer une autre structure de 100 Mo une milliseconde plus tard et s’attendre à ce que l’utilisation de la mémoire reste la même.

Ce n'est pas vrai avec la récupération de place. Les systèmes ramassés de déchets ont un certain retard à restituer la mémoire inutilisée au tas, ce qui peut être important. Si votre structure de 100 Mo devient hors de portée et qu'une milliseconde plus tard, votre programme configure une autre structure de 100 Mo, vous pouvez raisonnablement vous attendre à ce que votre système utilise 200 Mo pendant une courte période. Cette "période courte" peut prendre quelques millisecondes ou secondes, selon le système, mais il y a toujours un délai.

Si vous utilisez un PC avec des Go de RAM et de mémoire virtuelle, vous ne le remarquerez probablement jamais. Si vous utilisez un système avec des ressources plus limitées (par exemple, un système intégré ou un téléphone), vous devez prendre cela au sérieux. Ce n’est pas seulement théorique, j’ai personnellement constaté que cela créait des problèmes (comme lors du blocage du type de périphérique) lorsque je travaillais sur un système WinCE utilisant le .NET Compact Framework et évoluant en C #.

Graham
la source
Vous pouvez en théorie lancer un GC avant chaque affectation.
adrianN
4
@adrianN Mais dans la pratique, cela n'est pas fait parce que ce serait mental. Le point de vue de Graham est toujours valable: les GC impliquent toujours des frais généraux substantiels, soit en termes de temps d'exécution, soit en termes de mémoire excédentaire requise. Vous pouvez modifier cet équilibre vers les deux extrêmes, mais vous ne pouvez fondamentalement pas supprimer les frais généraux.
Konrad Rudolph
Le "retard" lors de la libération de la mémoire est davantage un problème dans un système à mémoire virtuelle que dans un système avec des ressources limitées. Dans le premier cas, il peut être préférable pour un programme d’utiliser 100 Mo au lieu de 200 Mo même si le système en dispose de 200 Mo. Dans le second cas, il ne serait pas avantageux de faire fonctionner le GC plus tôt que nécessaire, à moins que des retards ne soient plus acceptables pendant un certain temps. parties du code que pendant d'autres.
Supercat
Je ne vois pas comment cela tente de répondre à la question (CS).
Raphaël
1
@Raphael J'ai expliqué un problème bien connu avec le principe de la collecte des ordures, qui est (ou devrait être) enseigné dans CS comme l'un de ses inconvénients fondamentaux. J'ai même donné mon expérience personnelle d'avoir vu cela dans la pratique, pour montrer que ce n'était pas un problème purement théorique. Si vous ne comprenez pas quelque chose à ce sujet, je me ferai un plaisir de vous parler pour améliorer votre connaissance du sujet.
Graham
4

La question suppose que la désallocation est quelque chose que le programmeur est supposé déduire des autres parties du code source. Ce n'est pas. "A ce stade du programme, la référence mémoire FOO n'est plus utile", les informations sont connues uniquement dans l'esprit du programmeur jusqu'à ce qu'elles soient codées (dans des langages procéduraux) dans une instruction de désallocation.

Ce n'est théoriquement pas différent de toute autre ligne de code. Pourquoi les compilateurs n'insèrent-ils pas automatiquement "À ce stade du programme, vérifiez l'entrée du registre BAR" ou "si l'appel de fonction renvoie une valeur différente de zéro, quittez le sous-programme en cours" ? Du point de vue du compilateur, la raison en est "l'incomplétude", comme indiqué dans cette réponse . Mais tout programme souffre d'incomplétude quand le programmeur ne lui dit pas tout ce qu'il sait.

Dans la vraie vie, les désallocations sont du gruntwork ou du warmplate; notre cerveau les remplit automatiquement et grogne, et le sentiment que "le compilateur pourrait le faire aussi bien ou mieux" est vrai. En théorie, cependant, ce n'est pas le cas, même si, heureusement, d'autres langues nous offrent plus de choix de théorie.

Travis Wilson
la source
4
"" A ce stade du programme, la référence mémoire FOO n'est plus utile ", ce sont des informations connues uniquement dans l'esprit du programmeur", ce qui est clairement faux. a) Pour beaucoup de FOO, il est trivial de le comprendre, par exemple des variables locales avec une sémantique de valeur. b) Vous suggérez que le programmeur le sait toujours, ce qui est clairement une hypothèse trop optimiste; si cela était vrai, nous n'aurions pas de bogues graves car une mauvaise gestion de la mémoire est un logiciel essentiel pour la sécurité. Ce que nous faisons, hélas.
Raphaël
Je dis simplement que la langue a été conçu pour les cas où le programmeur ne connaît FOO est plus utile. Je suis d'accord, clairement, ce n'est pas généralement vrai, et c'est pourquoi nous avons besoin d'une analyse statique et / ou d'un ramassage des ordures. Ce que, houray, nous faisons. Mais la question du PO est la suivante: quand ces choses ne sont-elles pas aussi valables que des deallocs codés à la main?
Travis Wilson
4

Ce qui est fait: Il existe un ramasse-miettes et des compilateurs utilisant le comptage de références (Objective-C, Swift). Ceux qui font du comptage de référence ont besoin de l'aide du programmeur en évitant les cycles de référence trop forts.

La vraie réponse au "pourquoi" est que les auteurs de compilateur n'ont pas trouvé de solution suffisamment efficace et rapide pour le rendre utilisable dans un compilateur. Étant donné que les auteurs de compilateur sont généralement très intelligents, vous pouvez en conclure qu'il est très, très difficile de trouver un moyen suffisamment efficace et rapide.

L'une des raisons pour lesquelles c'est très très difficile est bien sûr que c'est indécidable. En informatique, lorsque nous parlons de "décidabilité", nous entendons "prendre la bonne décision". Les programmeurs humains peuvent bien sûr facilement décider où désallouer la mémoire, car ils ne se limitent pas aux décisions correctes . Et ils prennent souvent des décisions qui sont fausses.

gnasher729
la source
Je ne vois pas de contribution ici.
Babou
3

Dans des langages tels que C, le programmeur est censé insérer des appels pour libérer. Pourquoi le compilateur ne le fait-il pas automatiquement?

Parce que la durée de vie d'un bloc de mémoire est la décision du programmeur, pas celle du compilateur.

C'est ça. C’est la conception de C. Le compilateur ne peut pas savoir quelle était l’intention d’allouer un bloc de mémoire. Les humains peuvent le faire, car ils connaissent le but de chaque bloc de mémoire et savent quand ce but est servi pour le libérer. Cela fait partie de la conception du programme en cours d’écriture.

C étant un langage de bas niveau, les instances de transfert d’un bloc de votre mémoire à un autre processus ou même à un autre processeur sont assez fréquentes. Dans les cas extrêmes, un programmeur peut allouer intentionnellement une partie de la mémoire et ne plus l'utiliser, simplement pour exercer une pression mémoire sur d'autres parties du système. Le compilateur n'a aucun moyen de savoir si le bloc est toujours nécessaire.

Agent_L
la source
-1

Dans des langages tels que C, le programmeur est censé insérer des appels pour libérer. Pourquoi le compilateur ne le fait-il pas automatiquement?

En C et dans de nombreux autres langages, il est effectivement possible de faire en sorte que le compilateur fasse l’équivalent dans les cas où cela est clair au moment de la compilation: utilisation de variables à durée automatique (c.-à-d. Variables locales ordinaires) . Il incombe au compilateur de disposer de suffisamment d’espace pour ces variables et de le libérer lorsque leur durée de vie (bien définie) se termine.

Les matrices de longueur variable étant une caractéristique C depuis C99, les objets à durée automatique remplissent en principe pratiquement toutes les fonctions en C que remplissent les objets de durée calculable alloués dynamiquement. En pratique, bien sûr, les implémentations en C peuvent imposer des limites pratiques significatives à l’utilisation des VLA - c’est-à-dire que leur taille peut être limitée du fait de leur affectation en pile - mais il s’agit d’une considération pour la mise en oeuvre, pas pour la conception linguistique.

Les objets dont l'utilisation prévue ne permet pas de leur attribuer une durée automatique sont précisément ceux dont la durée de vie ne peut pas être déterminée au moment de la compilation.

PellMel
la source