Ist C++ Refactoring schwieriger als Java?
-
Fragensteller. schrieb:
Na, da stellt sich mir doch die Frage: Warum?
Ist es so wie oben vermutet?Audacia hat doch eigentlich schon die Antwort gegeben. Java zu parsen ist einfach, C++ zu parsen ist um Längen schwerer.
-
Es gibt ja Tools um C++ zu refactorn. Nur hat halt MS in ihrem VC++ bisher nichts eingebaut. Refactoring gab es für C# auch erst in VC#2005, hätten se ja auch schon vorher bringen können. Es gibt aber Addons für VC++ um Refactoring zu betreiben, sogar von drei Herstellern. Also denkt sich MS einfach "Warum sollen wird das noch machen?" Denn dafür ist ja eine Plugin-Fähigkeit gedacht, damit andere sowas anbieten können.
Unabhängig davon ob VC++ sowas drin hat: ja, C++-Code lässt sich schwieriger parsen und somit analysieren. Denn Refectoring ist ja mehr als nur einen text um zu bauen, da gehört ja auch immer eine Kontext-Analyse dazu.
Und es gibt deshalb Firmen die sich auf sowas spezialisiert haben. Und bevor MS ein schlechtes Refectoring einbaut, sollen sie das lieber lassen und ich kaufe mir ein Plugin von einem Hersteller der das kann.
http://www.devexpress.com/Products/NET/IDETools/RefactorCPP/
http://www.wholetomato.com/
http://xref-tech.com/xrefactory/main.html
http://plugins.netbeans.org/PluginPortal/faces/PluginDetailPage.jsp;jsessionid=3fe27af143cb2957bde621917986e?pluginid=4024
http://www.refpp.com/
-
Artchi schrieb:
Also denkt sich MS einfach "Warum sollen wird das noch machen?" Denn dafür ist ja eine Plugin-Fähigkeit gedacht, damit andere sowas anbieten können.
[..]
Und es gibt deshalb Firmen die sich auf sowas spezialisiert haben. Und bevor MS ein schlechtes Refectoring einbaut, sollen sie das lieber lassen und ich kaufe mir ein Plugin von einem Hersteller der das kann.Das ist wohl eher dem umsichtigen Management der Visual Studio Abteilung zuzurechnen, sowas ist bisher nicht allgemeine Microsoft-Politik gewesen, im Gegenteil. Siehe IE, Media Player, Doublespace, Defrag, Windows Firewall etc.
-
Refactoring für C++ ist immens viel komplizierter als Refactoring für Java (oder C# oder ...). Ein paar Faktoren die da mit reinspielen:
- Der Präprozessor
- Die defines & includes im speziellen, vor allem wenn man mehrere "Konfigurationen" hat (man denke an _DEBUG/NDEBUG).
- Die wesentlich kompliziertere Syntax von C++
- Argument Dependent Lookup und Overloads im speziellen
Aus dem Grund gibt es auch (noch) kein mir bekanntes Produkt welches wirklich "hochwertiges" Refactoring für C++ anbietet. Visual Assist X ist ganz nett, hat aber leider auch noch genug Bugs.
-
auch wenn die c++ syntax aufwendiger ist, als die java syntax, denke ich nicht, dass es soviel komplizierter wäre, eine refaktorierung anzubieten, wie eclipse für java.
was allerdings komplizierter ist, ist der bau eines c++ compilers. genau das hat eclipse nämlich auf java seite getan, um all diese tollen möglichkeiten anzubieten. eclipse bringt einen eigenen java compiler mit (der in hinsicht auf generische typen leider nicht 100% kompatibel zum sun compiler ist), der den code für die IDE entsprechend aufbohrt und markiert. das ist auch der grund, warum eclipse es schafft, jedweden "fehler" schon während des tippens anzuzeigen. und sehr wahrscheinlich auch mit ein grund, warum visual studio von microsoft (oder auch die älteren borland IDEs) so viele komfortfunktionen anbietet
compiler und ide aus einer hand.
-
thordk schrieb:
auch wenn die c++ syntax aufwendiger ist, als die java syntax, denke ich nicht, dass es soviel komplizierter wäre, eine refaktorierung anzubieten, wie eclipse für java.
was allerdings komplizierter ist, ist der bau eines c++ compilers. genau das hat eclipse nämlich auf java seite getan, um all diese tollen möglichkeiten anzubieten. eclipse bringt einen eigenen java compiler mit (der in hinsicht auf generische typen leider nicht 100% kompatibel zum sun compiler ist), der den code für die IDE entsprechend aufbohrt und markiert. das ist auch der grund, warum eclipse es schafft, jedweden "fehler" schon während des tippens anzuzeigen. und sehr wahrscheinlich auch mit ein grund, warum visual studio von microsoft (oder auch die älteren borland IDEs) so viele komfortfunktionen anbietet
compiler und ide aus einer hand.Diese Fähigkeiten von Eclipse die du auf den speziellen Compiler schiebst, hat
IntelliJ IDEA auch ohne eigenen Compiler.
-
thordk schrieb:
auch wenn die c++ syntax aufwendiger ist, als die java syntax, denke ich nicht, dass es soviel komplizierter wäre, eine refaktorierung anzubieten, wie eclipse für java.
was allerdings komplizierter ist, ist der bau eines c++ compilers.
Ich glaube, Du hast nicht genau verstanden, wie Refactoring eigentlich funktioniert. Um Refactoring anzubieten, muss nämlich ein Großteil des Compilers (mindestens das gesamte Frontend) nachgebaut werden. Die meisten der von Artchi genannten Refactoring-Tools haben sich (für teures Geld!) den Quellcode eines C++-Compilers gekauft (ich habe den Namen der Firma vergessen, die das Compiler-Frontend herstellt).
Das Problem ist, dass gerade das Frontend für C++ recht kompiliert ist, was zum Großteil an den mächtigen Templates und dem daraus resultierenden komplexen Namens-Lookup liegt.
Redhead schrieb:
Diese Fähigkeiten von Eclipse die du auf den speziellen Compiler schiebst, hat
IntelliJ IDEA auch ohne eigenen Compiler.
Auch IntelliJ IDEA verwendet dazu intern einen Compiler (bzw. Teile davon). Wie sonst soll das denn Deiner Meinung nach funktionieren?
-
Grammatik-basiertes Parsen der Eingabe??
Da die Syntax bekannt ist, sollten sich doch Identifier von Variablen, Klassen etc doch recht schnell auffinden lassen??
Ich verstehe zwar, dass der Ablauf durch die Grammatik recht aufwendig sein kann und ich die Grammatik erstmal haben muss, aber wozu benötige ich dann noch einen konkreten Compiler?
-
crashterpiece schrieb:
Grammatik-basiertes Parsen der Eingabe??
Da die Syntax bekannt ist, sollten sich doch Identifier von Variablen, Klassen etc doch recht schnell auffinden lassen??
Ich verstehe zwar, dass der Ablauf durch die Grammatik recht aufwendig sein kann und ich die Grammatik erstmal haben muss, aber wozu benötige ich dann noch einen konkreten Compiler?
Was, Deiner Meinung nach, *ist* denn ein konkreter Compiler? Abgesehen davon reicht es eben *nicht* aus, die Grammatik umzusetzen, da gewisse Aspekte der Syntax und Semantik (das gesamte Typensystem, Name-dependent lookup, Template-Auflösung, SFINAE) einfach nicht in der Grammatik einer Sprache repräsentiert sind. Das ist übrigens in Java nicht anders. Es reicht nicht, anhand der Grammatik den Parsebaum aufzubauen – dadurch könnte man nicht mal die IDE-Funktion „gehe zur Definition“ oder „finde alle Referenzen“ implementieren. Und das bedeutet, dass man nicht mal die simpelste aller Refactor-Aktionen, nämlich das „Umbenennen“ implementieren könnte, weil der Parsebaum absolut keine Informationen darüber enthält, welche Variable wo deklariert ist.
-
thordk schrieb:
auch wenn die c++ syntax aufwendiger ist, als die java syntax, denke ich nicht, dass es soviel komplizierter wäre, eine refaktorierung anzubieten, wie eclipse für java.
Java und C# haben in dieser Hinsicht einen Schwerwiegenden Vorteil: Reflektion. Du kannst über einen beliebigen Typ sehr detailierte Informationen abfragen. In C++ geht das nicht, oder nur sehr maginal (RTTI). Ich kann mir gut Vorstellen das auch einige Refaktoringansätze mittels Reflektion deutlich leichter umzusetzen sind.
Zudem funktionieren Templates in C++ etwas anders als die Entsprechungen in Java/C# (Mit C++ Templates geht deutlich mehr, was die ganze Problematik noch weiter verschärft). Grundsätzlich kann man sagen: C++ hat einen deutlich größeren Sprachumfang, und eine wesentlich andere Herangehensweise als Java/C#, letztere haben beim Refaktioring extreme Vorteile da die Sprachen bewusst einfacher gestaltet sind.
cu André
-
Wie von mir schon gesagt, ist es doch nicht einfach mit Textersetzung u.ä. getan. Ob die Refactoring-Hersteller einen Frontend-Compiler gekauft haben, weiß ich nicht. Sie werden aber auf jeden Fall etwas haben, das die Leistung eines solchen Frontend-Compilers bringt. Denn die Codecompletion von VisualAssist X funktioniert z.B. so wie ich erwarte. Gaaanz selten das VAX etwas nicht auflösen kann. Ja, sogar Syntaxfehler werden teilweise on the fly erkannt und rot unterstrichen. Funktioniert zwar auch nicht immer, aber kann manchmal schon hilfreicher sein, als wenn ich neu compilieren muß.
So, zu MS: die arbeiten ja gerade daran, ihren Compiler umzubauen um genau zusein fangen die den komplett neu an. Eben weil er für Intellisense u.ä. nicht mehr zu gebrauchen ist. Ist halt schon über 20 Jahre alt der MS-Compiler. Und wenn die das fertig haben, kann ich mir gut vorstellen, das die Intellisense endlich basser wird und auch Refactoring von MS einfacher implementiert werden kann.
-
Ein paar sehr interessante Refactorings für eclipse/CDT gibt es mit folgendem plugin: http://ifs.hsr.ch/Projekte/Projekte/C_Refactorings.
Hier eine unvollständige Auflistung:- declare method
- implement method
- extract constant
- extract function
- extract baseclass
- extract subclass
- move field
- move method
- generateGetterSetter
- ...
<OFFTOPIC zweck="Werbung für eclipse">
Außerdem bietet eclipse/CDT das beste (differenzierteste) Syntax-Highlighting, das es zur Zeit gibt. Es kann sogar zwischen Aufrufen von Code aus dem eigenen Projekt und dem Code aus "includeten" Bibliotheken, die nicht dem Projekt angehören, unterschieden werden, ganz zu schweigen von der Unterscheidung des Aufrufs statischer Methoden, normaler Methoden und Funktionen. Natürlich können auch verschiedene Typsorten (typedefs, Klassen, native Typen, ...) verschieden hervorgehoben werden.Die Intellisense-Funktion funktioniert bei der aktuellen eclipse/CDT Version auch meistens sehr gut. Die einzigen mir aufgefallenen Situationen, wo es nicht funktioniert, beziehen sich auf die Überladung der Operatoren [] und (). Gibt z. Bsp. ein überladener Operator () ein Objekt zurück auf das man direkt zugreifen möchte, werden die Member des zurückgegebenen Objekts nicht angezeigt.
Beispiel:meineAutoErstellung("Mercedes").hupe()//hupe() wird nicht nach dem Punkt angezeigt, wenn "meineAutoErstellung" ein Objekt mit überladenem Operator () istEs funktioniert aber wunderbar, wenn man die Rückgabe vorher zuweist:
Mercedes m = meineAutoErstellung("Mercedes"); m.hupe(); //hupe() wird nach dem Punkt angebotenBis auf diese Ausnahme hat die Intellisense Funktion bei mir immer funktioniert, wenn auch manchmal einer der Befehle "Index->Rebuild", "Index->Update with modified files" oder "Index->Freshen all files" über das Kontextmenü nötig war.
</OFFTOPIC>Ansonsten gilt, wie schon gesagt wurde, Refactoring ist, wegen der Feature-Vielfalt von C++, wesentlich schwieriger für diese Sprache zu implementieren.
-
Vieles von dem was du aufführst bzgl. INtellisense und Syntaxcoloring kann VAX auch. Aber natürlich ist es erfreulich, das es mittlerweile mehrere IDEs gibt, die sowas können.

-
@Artchi: Ich habe mir VAX gekauft und verwende es mit VS 2005, und ich habe mir Eclipse für C++ angesehen. Was Syntax Coloring angeht kann VAX nichtmal annähernd mit Eclipse mithalten

Refactoring weiss ich nicht, hab ich mit Eclipse nicht ausprobiert. VAX ist da stellenweise aber auch ziemlich doof (findet Referenzen nicht, macht keine Vorschläge weil's die Klasse X grad mal wieder nicht mag etc.).