Question

Pourquoi ne peut-on pas écrire un compilateur qui gère ce qui doit être géré en code C ++ (c'est-à-dire pour le rendre "compatible CLR")?

Peut-être avec quelques compromis, comme interdire les pointeurs void dans certaines situations, etc. Mais tous ces mots-clés supplémentaires, etc. Quel est le problème devant être résolu par ces ajouts?

J'ai quelques réflexions sur certains aspects et sur ce qui pourrait être difficile à résoudre, mais une bonne explication solide serait très appréciée!

Était-ce utile?

La solution

Je ne suis pas d'accord avec les réponses jusqu'à présent.

Le principal problème à comprendre est qu'un compilateur C ++ crée un code adapté à un environnement très idiot. Même un processeur moderne ne connaît pas les fonctions virtuelles, diable, même les fonctions sont exténuantes. Un processeur ne se soucie vraiment pas que le code de gestion des exceptions pour dérouler la pile soit en dehors de toute fonction, par exemple. Le processeur traite les séquences d'instructions, avec sauts et retours. Les fonctions n’ont certainement pas de noms en ce qui concerne la CPU.

Ainsi, tout ce qui est nécessaire pour supporter le concept de fonction est mis là par le compilateur. Par exemple. Les vtables sont juste des tableaux de la bonne taille, avec les bonnes valeurs du point de vue des processeurs. __ func __ se termine sous la forme d'une séquence d'octets dans la table des chaînes, dont le dernier est 00.

Désormais, rien ne dit que l'environnement cible doit être muet . Vous pouvez certainement cibler la machine virtuelle Java. Encore une fois, le compilateur doit renseigner ce qui n'est pas proposé nativement. Pas de mémoire brute? Puis allouez un tableau d'octets volumineux et utilisez-le à la place. Pas de pointeurs bruts? Utilisez simplement des indices entiers dans ce tableau d'octets volumineux.

Le problème principal est que le programme C ++ semble assez méconnaissable de l'environnement d'hébergement. La JVM n'est pas idiote, elle connaît les fonctions, mais elle s'attend à ce qu'elles soient membres de la classe. Il ne s'attend pas à ce qu'ils aient < et > dans leur nom. Vous pouvez contourner cela, mais vous vous retrouvez avec un nom maléfique. Et contrairement au nom mangling, ce type de nom n'est pas destiné aux lieurs C mais aux environnements intelligents. Ainsi, son moteur de réflexion peut être convaincu qu'il existe une classe c__plus__plus avec la fonction membre __ namespace_std__for_each__arguments_int_pointer_int_pointer_function_address , et c'est toujours un bel exemple. Je ne veux pas savoir ce qui se passe si vous avez un std :: map de chaînes pour inverser les itérateurs.

L’inverse est en réalité beaucoup plus facile, en général. Pratiquement toutes les abstractions d'autres langages peuvent être masquées en C ++. Collecte des ordures? C'est déjà permis en C ++ aujourd'hui, vous pouvez donc le supporter même pour void * .

Une chose que je n’ai pas encore abordée est la performance. Émuler de la mémoire brute dans un tableau d'octets volumineux? Cela ne va pas être rapide, surtout si vous mettez des doubles en eux. Vous pouvez jouer à beaucoup de trucs pour le rendre plus rapide, mais à quel prix? Vous n'allez probablement pas obtenir un produit commercialement viable. En fait, vous pourriez utiliser un langage combinant les pires aspects du C ++ (comportement inhabituel dépendant de la mise en œuvre) et les pires éléments d’une machine virtuelle (lent).

Autres conseils

Le code correct existant, c'est-à-dire le code écrit conformément au standard C ++, ne doit pas modifier son comportement par inadvertance.

Eh bien, C ++ / CLI est principalement conçu pour être un liant entre le code géré et le code non géré. En tant que tel, vous devez avoir la capacité de mélanger des concepts gérés et non gérés. Vous devez être en mesure d’allouer des objets gérés et non liés dans le même code. Il n’ya donc aucun moyen de contourner des mots clés distincts.

Pourquoi ne pouvez-vous pas compiler du code C ++ natif ciblant le CLR?

Oui, vous avez bien deviné, il y aurait trop de compromis, cela le rendrait inutile. Je voudrais juste citer trois exemples ...

1.) Modèles: C ++ les prend en charge, mais pas le CLR (les génériques sont différents). Vous ne pouvez donc pas utiliser la STL, le boost, etc. dans votre code.

2.) Héritage multiple: pris en charge en C ++, pas en CLI. Vous ne pouvez même pas utiliser la classe standard iostream et ses dérivés (comme stringstream, fstream), qui héritent à la fois d'istream et d'ostream.

Presque aucun code ne serait compilé, vous ne pouviez même pas implémenter la bibliothèque standard.

3.) Collecte des ordures: La plupart des applications C ++ gèrent leur mémoire manuellement (à l'aide de pointeurs intelligents, etc.), le CLR dispose d'une gestion automatique de la mémoire. Ainsi, le style C ++ " new " et " supprimer " serait incompatible avec "gcnew", rendant le code C ++ existant inutile pour ce nouveau compilateur.

Si vous deviez supprimer toutes les fonctionnalités importantes, même la bibliothèque standard et qu'aucun code existant ne compilerait ... alors quel est le but?

Tout d’abord, la distinction entre " simple C ++ " et "géré en C ++". était intentionnel, car l’un des objectifs de MC ++ était de créer un pont entre le code C ++ existant et le CLR.

Ensuite, il y a trop de fonctionnalités C ++ qui ne rentrent pas dans le modèle CLR. Héritage multiple, modèles, arithmétique de pointeur ... Sans un tracé clair, les programmeurs seraient voués à faire face à des erreurs cryptiques, à la compilation et à l'exécution.

Je pense que cela est dû au fait que l'ajout de fonctionnalités de code managé au C ++ ralentirait le C ++ et rendrait le compilateur plus complexe. À tel point que C ++ perdrait ce pour quoi il avait été conçu. L’un des avantages du C ++ est que c’est un langage agréable à utiliser, qui est assez basique et pourtant quelque peu portable. Et c'est probablement ce que le comité de standard C ++ prévoit de faire en sorte que cela reste ainsi. Quoi qu’il en soit, je ne pense pas que le C ++ puisse jamais être entièrement "géré", car cela voudrait dire que les programmes écrits en C ++ ont besoin d’une machine virtuelle à exécuter. Si tel est le cas, pourquoi ne pas simplement utiliser C ++ / CLI?

Le framework Qt fait presque cela. C'est à dire. il comporte des pointeurs intelligents, qui sont automatiquement définis sur null lorsque l'objet auquel ils pointent est détruit. Et c’est quand même un C ++ natif, après analyse par moc (compilateur de méta-objets).

Oui, je suppose que le C ++ pourrait être géré. Mais alors. NET aurait besoin d'être réécrit pour C ++ et non avec un parti pris pour BASIC. Avec plusieurs langues sous le même toit. Certaines fonctionnalités doivent disparaître. C'était un choix entre VB.NET ou C ++ .NET, et VB.NET a été choisi. La chose amusante que j’entends, c’est que C # est plus populaire que VB.NET (même si je n’utilise ni l’un ni l’autre!).

Le .NET CLR requiert qu'aucune référence à un objet géré ne puisse exister, sauf si l'exécution est inconnue, sauf si l'objet est épinglé; Pour obtenir de bonnes performances, les objets doivent être épinglés le moins possible. Etant donné que le .NET CLR ne peut pas comprendre toutes les structures de données utilisables dans C ++, il est impératif qu'aucune référence à des objets gérés ne soit jamais persistée dans de telles structures. Il serait possible d'avoir " ordinaire " Le code C ++ interagit avec le code .NET sans aucune modification du langage C ++, mais constitue la seule façon pour le code C ++ de conserver une sorte de " référence " Pour n'importe quel objet .NET, il faudrait qu'un code quelconque sur le côté .NET attribue à chaque objet un descripteur, et conserve un tableau statique des objets associés aux descripteurs. Le code C ++ qui voulait manipuler les objets devrait alors demander au wrapper .NET d’effectuer une opération sur l’objet identifié par un handle. L’ajout de la nouvelle syntaxe permet au compilateur d’identifier les types d’objets que le framework .NET doit connaître et de leur imposer les restrictions nécessaires.

La première chose à considérer est tout ce qui rend c ++ "rapide" disparaîtra. un système de récupération de place complet en c ++ est pratiquement impossible. parce que c ++ , vous pouvez avoir un pointeur presque n'importe où dans le code. les informations de type à l'exécution deviennent coûteuses si elles ne sont pas directement intégrées à la le système de langues lui-même. vous pouvez tirer parti des véritables performances natives. le modèle disparaitra. les vrais indicateurs disparaîtront. l'accès direct à la mémoire a disparu.

liste des éléments à appliquer

1. no direct pointers(pointers will get replace with complex refernces)
2. templates (generics pay for preformance)
3. simple c-style arrays (will get wrapped with array structures)
4. programmer no longer has control of whether data is on the stack or
the heap.
5. garbage collection will be enforced(this will cause the most changes to the syntax)
6. runtime type data will get added extensively to the code.
(larger code size)
7.  inlining will become more difficult for the compiler
(no more inline key word)
8. no more inline assembly.
9. the new langauge by now will become incompatible c code.(unless you go through hoops) 

Je suis d'accord avec 5hammer! Si je quitte Java et d’autres langages gérés, ce n’est pas pour rien: avoir le plein contrôle de l’ordinateur, gérer la mémoire, gérer la mémoire moi-même, contrôler le mode d’exécution de mon code par l’ordinateur, intégrer les bibliothèques C (comme Lua). Si je perds cette flexibilité, je laisserais simplement C ++ et retomberais sur C, et si C devenait trop gérée, j'irais chez assembler.

Les langues gérées sont les pires de toutes les plates-formes de jeu / programmes complexes, car elles vous enchaînent dans une sorte de sandbox sans accès direct au matériel et sont beaucoup plus lentes que les langages compilés.

Le but principal du C ++ avait toujours été Performence. C'est l'un des meilleurs langages pour les grands jeux. Et sans ce langage, de nombreux jeux n'existeraient pas!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top