[ad_1]
Personnellement, je ne connais qu’un seul interpréteur C++ utilisé par Root (CINT, développé au CERN). Je me suis demandé pourquoi il y en avait si peu, et la réponse évidente est que le C++ est un langage très complexe à analyser. Personne sensé ne prendrait la peine d’écrire un analyseur C++ à partir de zéro…
Cependant, il existe des analyseurs C++ faisant partie des compilateurs, dont certains sont open source. Il m’est venu à l’esprit qu’il pourrait être possible d’interpréter le code assembleur émis par l’analyseur en déplacement. Ce serait comme un compilateur JIT qui émet du bytecode à interpréter par une machine virtuelle. Un problème qui me vient à l’esprit est l’utilisation de différents fichiers sources qui autrement conduiraient à plusieurs fichiers objets devant être liés. C’est effectivement une limitation, mais pas très grave à mon avis.
Pourtant, il semble que personne n’ait fait cela, ce qui signifie normalement que ce n’est pas aussi facile qu’il y paraît (non pas que mon idée soit triviale, mais quand même). Je me demandais quels seraient les problèmes avec mon idée… Quelqu’un voudrait-il commenter ?
Solution 1
Veuillez consulter les commentaires sur la question, par bling (bonne idée sur C++/CLI) et par moi-même.
Le fait est que CINT n’est pas un interpréteur C++. CINT n’est pas un interpréteur C++. C’est clairement indiqué ici :
Le langage est un langage simplifié basé sur C et C++.
Voir également: http://root.cern.ch/drupal/content/cling[^].
Que diriez-vous d’une alternative mentionnée dans l’article Wikipédia référencé ci-dessus, « Ch » ? Ce n’est pas exactement un interpréteur C++, c’est un interpréteur d’un langage spécial :
http://en.wikipedia.org/wiki/Ch_%28computer_programming%29[^],
Rien d’autre? “Pike”, également basé uniquement sur C et C++ (Wikipedia dit même “influencé par”) :
http://en.wikipedia.org/wiki/Pike_%28programming_langue%29[^],
Quant au « vrai » langage C++, certains pensent qu’il ne convient pas à un interprète ; le sujet est tout simplement trop complexe pour discuter de mes considérations de manière Rapide Questions et réponses. Je ne peux pas le prouver ici et je n’en suis pas sûr à 100 %, j’ai tendance à penser que c’est possible de le prouver. Je serais assez surpris si quelqu’un me prouvait le contraire.
Solution 3
Citation:Personnellement, je ne connais qu’un seul interpréteur C++ utilisé par Root (CINT, développé au CERN). Je me suis demandé pourquoi il y en avait si peu, et la réponse évidente est que le C++ est un langage très complexe à analyser. Personne sensé ne prendrait la peine d’écrire un analyseur C++ à partir de zéro…
Il y a ici quelques questions importantes : quel est votre objectif et pourquoi un interpréteur C/C++ serait-il la meilleure (ou du moins une raisonnablement bonne) solution à ce problème ? “Quel est ton but?” et “Pourquoi X est-il une bonne solution ?” sont généralement de très bonnes premières questions à poser avant de perdre un temps précieux à mettre en œuvre une solution.
C/C++ n’est pas pratique en tant que langage interprété basé sur une console pour de nombreuses raisons et les gens n’aiment généralement pas perdre de temps à implémenter des outils qui ne sont pas pratiques (enfin, peut-être ceux qui ont beaucoup de temps pour s’amuser et apprendre et/ou ceux qui ne peut pas prévoir les aspects peu pratiques).
Implémenter un interpréteur pour un langage dynamique (comme Python) avec des variables typées dynamiquement et des « fonctions liées dynamiquement » est beaucoup plus facile et moins sujet aux erreurs que de faire la même chose avec C/C++. Écrire l’ensemble de l’analyseur, du compilateur et de l’interprète pour un langage dynamique simple est assez simple et rapide. L’interpréteur lui-même n’a pas besoin d’être très performant car il est généralement utilisé uniquement pour exécuter une logique de haut niveau, du code collé. Si quelque chose est critique en termes de performances, vous pouvez l’implémenter en tant que module C/C++ natif pour votre interpréteur et le lier au langage interprété dynamiquement. À mon avis, vous n’avez pas vraiment réfléchi aux problèmes qui pourraient survenir avec les interpréteurs C/C++. Je pourrais écrire un roman sur eux. Voici les problèmes les plus intéressants et suffisamment importants :
C/C++ nécessite des déclarations avancées. Dans un langage interprété pratique, il n’y a pas de déclarations directes et il n’y a pas de déclarations/définitions séparées. Mais ce n’est qu’une infime partie d’un problème plus sérieux : le C/C++ est peu pratique pour être utilisé comme langage interprété. Il s’agit d’un ensemble de problèmes qui impliquent à la fois des problèmes de conception du langage et des problèmes pratiques d’utilisation en tant que langage interprété. En python, je peux facilement définir une fonction X qui appelle une fonction Y inexistante et je suis autorisé à définir cette fonction Y plus tard. Ensuite, je peux exécuter X. Plus tard, si je le souhaite, je peux changer complètement la définition de Y (peut-être avec de nouveaux paramètres initialisés par défaut pour être rétrocompatibles avec la définition précédente) et une autre exécution de X utilise immédiatement la nouvelle définition de Y. Je peux exécuter X même s’il appelle une fonction Z qui n’a pas encore été définie et ce n’est pas un problème si l’exécution de X avec les paramètres d’entrée réels ne s’exécute pas réellement dans la branche qui appellerait Z. Dans un Interpréteur C++, que se passe-t-il si je modifie la définition d’un modèle très basique (par exemple : un tableau dynamique) qui est utilisé par de nombreuses fonctions précédemment définies (par exemple en tant que fonctions en ligne) ? Comment savoir quels blocs de code doivent être recompilés dans votre interpréteur afin d’utiliser les nouvelles fonctions en ligne ? Que se passe-t-il si la recompilation de certaines de ces fonctions échoue avec la nouvelle définition ? Vous n’avez pas de problèmes sérieux comme celui-ci avec des langages dynamiques comme Python. Traiter de tels scénarios dans un interpréteur non dynamique serait un énorme problème, et ce n’étaient que deux problèmes “simples/basiques”, ce n’est que la pointe de l’iceberg. Je programme en C/C++ depuis plus d’une décennie et je n’ai jamais ressenti le besoin d’un interpréteur C/C++.
Citation:Cependant, il existe des analyseurs C++ faisant partie des compilateurs, dont certains sont open source. Il m’est venu à l’esprit qu’il pourrait être possible d’interpréter le code assembleur émis par l’analyseur en déplacement. Ce serait comme un compilateur JIT qui émet du bytecode à interpréter par une machine virtuelle. Un problème qui me vient à l’esprit est l’utilisation de différents fichiers sources qui autrement conduiraient à plusieurs fichiers objets devant être liés. C’est effectivement une limitation, mais pas très grave à mon avis.
J’ai commencé à rédiger une réponse, mais elle est devenue trop longue et complexe car elle analysait votre problème selon de nombreux aspects transversaux différents. Au lieu de cela, j’écris ici quelques-unes de mes conclusions.
Vous devriez répondre aux questions que j’ai postées dans le paragraphe précédent. D’après votre question, je pense que votre objectif est peut-être simplement de créer UN Interpréteur C++ avec le moins de travail investi – je suppose cela parce que vous souhaitez réutiliser des éléments (unités de compilation, fichiers objets) des compilateurs existants. Mon problème avec cela est que les gens font quelque chose avec « le moins de travail investi » lorsqu’ils doivent faire quelque chose qu’ils n’aiment pas. D’un autre côté, s’ils font quelque chose juste pour s’amuser, comme passe-temps ou dans un but spécifique, cela ne les dérange généralement pas de faire beaucoup de travail. Dans le cas d’un interpréteur C/C++, toutes les solutions semblent impliquer beaucoup de travail.
En fonction du compilateur et des paramètres du compilateur, les fichiers objets peuvent contenir autre chose que ce dont vous avez besoin. Ils ne sont pas standardisés et même le même compilateur peut y mettre des déchets complètement inutiles avec certains paramètres (comme LTCG). OMI, il serait plus pratique d’écrire un backend pour émettre ce dont vous avez besoin au lieu d’essayer de l’analyser à partir de fichiers objets.
Solution 4
Ma raison spéculative : il semble que personne n’en ait eu besoin par rapport à l’effort nécessaire pour le faire. Autrement dit, vous pourrez peut-être construire une tour Eiffel dans votre jardin, à condition d’avoir l’espace, le matériel, les personnes, un terrain suffisamment bon, etc. et vous pouvez le faire pour votre propre plaisir. 😉
La différence entre le C et le C++ est celle indiquée dans la norme C++ :
En plus des fonctionnalités fournies par C, C++ fournit des types de données supplémentaires, des classes, des modèles, des exceptions, des espaces de noms, une surcharge d’opérateurs, une surcharge de noms de fonctions, des références, des opérateurs de gestion de magasin gratuits et des fonctionnalités de bibliothèque supplémentaires.
Si vous passez à C++11, vous pouvez ajouter des expressions lambda et plusieurs autres parties, toutes principalement du sucre syntaxique dans le sens où elles résument quelque chose qui est principalement lié à l’analyseur et qui pourraient également être réalisées (sinon fastidieuses) par d’autres moyens.
Quels sont les résultats en tant qu’éléments d’exécution de l’analyse des fonctionnalités ci-dessus ?
– types de données supplémentaires : quelques types char/numériques supplémentaires intégrés
– classe : fonctions d’instance étendues avec this
paramètre
– classe : héritage avec classe de base comme sous-objet d’une classe dérivée
– classe : appels de fonctions implicites spéciales (ctor, dtor, etc.)
– classe : vtable pour les appels de fonctions virtuelles
– classe : l’ordre des définitions (pour la plupart) n’a pas d’importance dans les classes – seule la recherche de nom est affectée
– modèles : classes ou fonctions générées basées sur un type ou des valeurs intégrales constantes
– exceptions : flux de contrôle supplémentaire et notamment code de nettoyage-comptabilité
– espaces de noms : “sucre syntaxique” (les types, objets et fonctions uniques sont définis et appelés)
– surcharge : “sucre syntaxique” (l’analyseur crée des appels aux fonctions correctes)
– références : « sucre syntaxique », entraîne des pointeurs ou aucun code d’exécution du tout
– nouveau/supprimer : mémoire de bas niveau malloc/free plus appels ctor/dtor
– bibliothèques : collection d’éléments basés sur les fonctionnalités du langage
– expression lambda : “sucre syntaxique” (classe de foncteurs implicite)
-…
Il y a de vilains problèmes de détails à surmonter, mais techniquement, cela peut être considéré comme un C beaucoup plus étendu.
Donc, si vous disposez d’une interface C++ qui parvient à se traduire en C fonctionnellement équivalent, alors vous êtes arrivé au niveau CINT. Les problèmes tels que plusieurs fichiers et le référencement de bibliothèques et de fichiers objets ne sont pas propres au C++ mais constituent un fait commun à tous les langages C*. Ainsi, vous pouvez réutiliser ces concepts de l’interprète de ces langages (CINT ?).
Mais encore une fois, la justification de l’effort dépend dans une large mesure du « gain » potentiel.
Acclamations
Et moi
Solution 5
Parce que C++ est un énorme langage de programmation. C’est tout simplement trop compliqué. Les interprètes sont créés pour des langages comme Python, JavaScript, non seulement parce qu’ils sont simples, mais ils sont destinés à être interprétés, ils sont dynamiques. La première implémentation de Python était un interpréteur ; pas un compilateur. Ce n’est pas seulement la raison. On sait déjà que le C++ est plus rapide que les langages interprétés une fois « compilé ». Mais on ne peut pas toujours attendre la même chose d’un interpréteur C++. C++ est sensible au contexte ; Le C++ est énorme ; C++ contient des génériques. Ainsi, la complexité du langage contribue à la lenteur du traitement du code source. Par exemple, consultez les vitesses de compilation de C++. Que se passera-t-il si vous interprétez la source ? Cela étant dit, un programme classique « hello world » ne prendra peut-être pas beaucoup de temps. Mais pensez à un programme utilisant largement des techniques génériques ?
Mais il existe toujours des interprètes comme CINT, Ch. Voir la page suivante :
Solution 2
Il est difficile de vraiment “résoudre” cette question – cela aurait peut-être été mieux dans un forum, mais voici mon 2c.
La définition du langage n’exclut pas vraiment de créer un interpréteur, mais le C++ a été réellement conçu comme un langage de bas niveau pouvant être utilisé pour du code extrêmement efficace. Le langage est extrêmement complexe, mais pas impossible à analyser (AFAIK, il nécessite vraiment un analyseur GLR ou un analyseur écrit à la main). Cela dit, la plupart des avantages du C++ viennent du fait qu’il peut être utilisé pour du code efficace, qui s’exécute à proximité de la machine. Les interprètes sont généralement utilisés pour des tâches de haut niveau, pour lesquelles une itération rapide pendant le développement est plus importante que la vitesse d’exécution.
Bref, ce serait un sacré boulot, et ça courrait comme un chien.
[ad_2]
コメント