41 votes

Conversion de source C en C ++

Comment vous y prendriez-vous sur la conversion d'un assez grand (>300 K), assez mature C code C++?

Le genre de C j'ai à l'esprit est divisé en fichiers correspondant grosso modo aux modules (c'est à dire moins précis que les typiques OO classe basée sur la décomposition), en utilisant une liaison interne au lieu des réceptions privées et des données, et de la liaison externe pour les fonctions publiques et les données. Les variables globales sont largement utilisés pour la communication entre les modules. Il y a un très vaste de l'intégration de la suite de tests disponible, mais aucune unité (c'est à dire le module) des tests de niveau.

J'ai en tête une stratégie générale:

  1. Tout compiler en C++C sous-ensemble et d'obtenir que le travail.
  2. Convertir des modules dans d'énormes classes, de sorte que toutes les références croisées sont limités par un nom de classe, mais en laissant toutes les fonctions et les données membres statiques, et obtenir que le travail.
  3. Convertir énorme classes dans les instances appropriées constructeurs et initialisé références croisées; remplacer le membre statique accès avec accès indirects, selon le cas; obtenir que le travail.
  4. Maintenant, l'approche du projet comme un mauvais compte OO application, et d'écrire des tests unitaires, où les dépendances sont traitables, et se décomposent dans des classes séparées, où ils ne sont pas; le but ici serait de passer d'un programme à l'autre à chaque transformation.

Évidemment, ce serait tout à fait un peu de travail. Existe-il des études de cas, les histoires de guerre là-bas sur ce genre de traduction? Les stratégies alternatives? D'autres conseils utiles?

Note 1: le programme est un compilateur, et probablement des millions d'autres programmes reposent sur son comportement ne change pas, donc en gros la réécriture est à peu près pas une option.

Note 2: la source de près de 20 ans, et a peut-être 30% de code de désabonnement (lignes modifiées + ajout / total des lignes) par an. Il est fortement maintenu et étendu, en d'autres termes. Ainsi, un des objectifs serait d'augmenter mantainability.

[Pour l'amour de la question, supposons que la traduction en C++ est obligatoire, et que le laisser dans C est pas une option. Le point de l'ajout de cette condition est d'éliminer le "laisser dans C" réponses.]

15voto

Head Geek Points 10874

Ayant tout juste commencé à peu près la même chose il y a quelques mois (sur dix-année-vieux projet commercial, à l'origine écrit avec le "C++ n'est rien, mais C avec puce structs" philosophie), je vous recommande d'utiliser la même stratégie que vous utilisez pour manger un éléphant: prendre une bouchée à la fois. :-)

Autant que possible, la découper en étapes qui peut être fait avec un minimum d'effets sur d'autres parties. La construction d'un système de façade, comme Federico Ramponi suggéré, c'est un bon début, une fois que tout a un C++ façade et communique à travers elle, vous pouvez modifier les données internes de modules avec la certitude qu'ils ne peuvent pas affecter de quelque chose d'extérieur à eux.

Nous avons déjà eu un partiel C++ interface du système en place (pour les petits refactoring efforts), de sorte que cette approche n'était pas difficile dans notre cas. Une fois que nous avons eu tout à une communication des objets en C++ (qui a pris quelques semaines, sur un tout autre code source de la branche et de l'intégration de toutes les modifications apportées à la branche principale, car ils ont été approuvés), il était très rare que nous n'arrivions pas à compiler un totalement version de travail avant que nous partions pour la journée.

Le changement n'est pas encore complet, nous avons mis en pause, deux fois pour des documents provisoires (nous visons un point de presse à quelques semaines d'intervalle), mais c'est bien sur le chemin, et aucun client ne s'est plaint au sujet de tous les problèmes. Nos gens de l'assurance qualité n'avons trouvé qu'un seul problème que je me souviens, aussi. :-)

12voto

Federico A. Ramponi Points 23106

Qu'en est-il de:

  1. Compiler tout dans le sous-ensemble C de C ++ et le faire fonctionner, et
  2. Mettre en œuvre un ensemble de façades en laissant le code C inchangé?

Pourquoi la "traduction en C ++ est-elle obligatoire"? Vous pouvez envelopper le code C sans la peine de le convertir en énormes classes, etc.

7voto

Ira Baxter Points 48153

Votre application a beaucoup de gens qui travaillent sur elle, et un besoin de ne pas être brisé. Si vous êtes sérieux au sujet de la conversion à grande échelle à un OO style, ce vous avez besoin est une transformation massive des outils pour automatiser le travail.

L'idée de base est de désigner des groupes de données sous forme de classes, et puis obtenez l'outil de refactoriser le code pour déplacer les données dans les classes, déplacer des fonctions simplement que les données dans ces classes, et la révision de tous les accès aux données à des appels sur les classes.

Vous pouvez faire un système automatisé de prédiagnostic de forme statistique des clusters pour avoir des idées, mais vous aurez toujours besoin d'une application consciente de l'ingénieur de décider de ce éléments de données doivent être regroupés.

Un outil qui est capable de faire cette tâche est notre Logiciel DMS Réingénierie Trousse à outils. DMS a fait fort C analyseurs pour la lecture de votre code, il saisit le code C comme compilateur de l'arbre de syntaxe abstraite, (et contrairement à un classique du compilateur) peut calculer à l'analyse des flux sur l'ensemble de votre 300K SLOC. DMS a une interface C++ qui peut être utilisé comme le "dos" de la fin; on écrit les transformations que la carte de la syntaxe C de syntaxe C++.

L'un des principaux C++ réingénierie de la tâche sur un grand système avionique donne une idée de ce à l'aide de DMS pour ce genre d'activité, c'est comme. Voir documents techniques à www.semdesigns.com/Products/DMS/DMSToolkit.html, plus précisément La ré-ingénierie de Composant C++ Modèles Via Programme Automatique de Transformation de

Ce processus n'est pas pour les faibles de cœur. Mais que n'importe qui chargée d'examiner le manuel de refactoring d'une application grand c'est déjà pas peur de travailler dur.

Oui, je suis associé avec la société, son architecte en chef.

5voto

nlaq Points 11379

Je voudrais écrire des classes C ++ sur l'interface C. Ne pas toucher le code C diminuera le risque d'erreur et accélérera considérablement le processus.

Une fois que votre interface C ++ est active; il s’agit alors d’une tâche triviale consistant à copier + coller le code dans vos classes. Comme vous l'avez mentionné, il est essentiel d'effectuer des tests unitaires au cours de cette étape.

3voto

Paul Nathan Points 22910

Votre liste semble correcte, sauf que je vous suggère de commencer par passer en revue la suite de tests et d'essayer de la resserrer le plus possible avant de procéder à tout codage.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X