Punkte, die mich an C++ stören

Hier kann über allgemeine Themen diskutiert werden, die sonst in kein Forum passen.
Insbesondere über Szene, Games, Kultur, Weltgeschehen, Persönliches, Recht, Hard- und Software.
Antworten
Psycho
Establishment
Beiträge: 156
Registriert: 16.09.2002, 14:23

Punkte, die mich an C++ stören

Beitrag von Psycho »

Hallo,

ich habe jetzt schon länger nichts mehr mit C++ gemacht, obwohl ich schnelle, kleine Programme liebe.
Leider hat es auch ein paar Nachteile, die dazu geführt haben, dass ich mich jedesmal etwas sträube, ein neues Projekt anzufangen. Meine Auflistung nach persönlichen Vorlieben und Nachteilen:

Gut:
  • Nativer Code
  • RAII
  • Keine Runtime-Typ-Info (wenig Overhead)
  • Stack-Variablen (schnell)
  • Keine Garbage-Collection
Schlecht:
  • Redundanz durch .h/.cpp
  • Meinung: STL sieht eklig aus (wieso vector statt list, wieso kein collection interface? Hat bestimmt seine Gründe, finde ich aber unintuitiv)
  • Kompilierzeit
  • Namespace-Syntax ist umständlich
  • Manuelle Erstellung von Verzeichnissen für Namespaces nötig
  • Template-Magie ist kompliziert und unübersichtlich
  • Keine Compile-Time Typ-Info (z.B. zur automatischen Serialisierung; ja, widerspricht sich eventuell mit dem Punkt oben)
Ich glaube, dass ich mehr Spaß am Programmieren mit C++ hätte, wenn ich eine IDE hätte, mit der ich besser zurecht komme und vor allem die .h/.cpp-Doppelung wegfallen würde. In den typischen Java-IDEs kann ich mit Rechtsklick->Neue Klasse->Package eintippen->Namen der Klasse eintippen->OK automatisch eine Klasse im richtigen Package und Verzeichnis erstellen.
In C++ hätte ich ebenfalls gerne Klassen, die in einem Namespace sind, im gleichnamigen Verzeichnis. Dazu fällt mir nur die Möglichkeit ein, jedesmal beim Erstellen einer Klasse in Visual Studio den Verzeichnisnamen per Hand zu ändern und dann um die ganze Datei oben "namespace XYZ {" und unten "}" zu schreiben. Das mag für einige eine Kleinigkeit sein, aber mich stört es jedesmal. Weiß jemand, ob ich nur Möglichkeiten der IDE übersehe oder sich der Vorgang vereinfachen lässt?

Zweiter dicker Punkt: Es wäre viel schöner, wenn ich die gesamte Klasse wie in Java in einer einzigen Datei hätte. Kann jemand einschätzen, wieviel Aufwand es wäre, einen Translator zu schreiben, der eine Datei automatisch in .h- und .cpp-Dateien zerlegt?
Mir ist bewusst, dass Translatoren einen Haufen Nachteile mit sich bringen, aber es wäre ein Anfang. Später kann man vielleicht ein LLVM-Frontend schreiben (auch wenn ich damit noch gar keine Erfahrung habe). Nach und nach kann dann die Sprache modifiziert werden, bis ich bei meiner persönlichen, idealen Sprache angelangt bin. ;) Es geht nur um Programme für mich selber und um meine persönliche Vorlieben, ich möchte explizit nicht die neue Super-Duper-Sprache für die Wirtschaft schreiben.

Code: Alles auswählen

namespace XYZ;

#include <iostream>

class MyClass
{
  private int a;

  MyClass(int a) {
    this->a = a;
  }

  public int getA() {
    return a;
  }
};

int main()
{
  MyClass myInstance(3);
  std::cout << myInstance.getA() << endl;
  return 0;
}
Ich denke über die Entwicklung des Translators nun schon einige Wochen nach und möchte ihn definitiv umsetzen. Leider stoße ich mit meinem Wissen an Grenzen, da ich (fast) keine Erfahrung mit Parsern und Lexern habe. Ein Problem ist z.B., dass in den Header natürlich nur die nötigsten Informationen sollen. D.h. nicht alle Includes, die in der Quelldatei stehen, kommen auch unbedingt in den Header. Nach Möglichkeit sollten Forward-Declarations verwendet werden. Aber um zu ermitteln, wann was verwendet werden soll oder kann, muss ich analysieren, ob eine Klasse überhaupt den vollständigen Typ kennen muss. Also muss ich prüfen, ob die Klasse von einer anderen erbt, ich muss prüfen, welche Typen die Member-Variablen haben etc.
Natürlich soll es auch normale Funktionen geben.

Vielleicht könnt ihr mir ein paar Denkanstöße geben, wie die Punkte am besten umgesetzt werden könnte. Oder einfach eure Meinung dazu sagen.
Ich freue mich auf eure Antworten.

Gruß
Psycho
Benutzeravatar
FlorianB82
Beiträge: 70
Registriert: 18.11.2010, 05:08
Wohnort: Darmstadt
Kontaktdaten:

Re: Punkte, die mich an C++ stören

Beitrag von FlorianB82 »

Wieso nervt dich denn genau die Aufteilung in cpp/hpp-Dateien? Was genau versprichst du dir davon, wenn alles in einer Datei steckt? Oder anders gesagt: Ich persönlich wäre noch mehr genervt von einer Riesendatei, die sowohl Interface als auch Implementierung enthält, und ansonsten keine Vorteile gegenüber der cpp/hpp Aufteilung bietet.

Ich persönlich finde die Aufteilung einer Klasse nicht verkehrt, allerdings nicht so, wie man sie bei naiver Aufteilung in cpp/hpp erhält. Imho wäre es toll, in der hpp das public interface der Klasse zu haben, und in der cpp den ganzen Rest (also private Interface sowie Implementierung). Leider ist das in C++ nicht direkt möglich, erst durch PIMPL & Konsorten bekomme ich etwas in der Richtung. Solch eine Aufteilung hätte dann aber neben einer gewissen Ästhetik auch eine Reihe handfester Vorteile (z.B.: nur das public Interface steckt im Header, ich kann also das private Interface ändern, ohne alles mögliche neu kompilieren zu müssen).

Das Problem, dass im Header nur die nötigsten Informationen stehen sollen (was auch immer das nun genau heißt), ist auch nicht unbedingt einfach. Im Falle der Includes kommt man noch mit dem Auflösen des Abhängigkeitenbaums/graphs aus, für andere Dinge (z.B. Erbschaftsbeziehungen) brauchst du schon fast einen vollständigen C++-Parser samt AST. Spätestens falls du irgendwelche Templates verarbeiten musst, wirds spaßig (wobei ich mir da gerade nicht sicher bin, ob diese ein Problem darstellen, da sie ja ohnehin zwingend in die Header wandern).

Was ich mir übrigens auch lästig vorstelle ist, dass in den von deinem Translator generierten Header Dinge auftauchen und auch wieder verschwinden, je nachdem wie der Rest des Programmes beschaffen ist. Das ist zwar prinzipiell logisch und richtig, aber ungewohnt und aus Designgründen auch nicht sonderlich schön.

Unterm Strich: Ich bräuchte sowas nicht - ich sehe einfach keinen großartigen Vorteil davon.

PS: Ist zwar nicht Kern deines Threads, wollte ich aber trotzdem nicht unkommentiert stehen lassen: Du kannst sehr wohl in C++ Garbage-Kollektoren einsetzen (indem du z.B. new und delete selbst definierst). Und es gibt auch durchaus solche Implementierungen. Und abgesehen davon: Ein Garbage-Kollektor muss nicht zwangsläufig ein Nachteil sein. Es gibt Situationen, wo du mit einem GC sprachunabhängig mehr Performance erreichst als durch manuelles Memory Management - zum Beispiel, wenn du auf verketteten Listen arbeitest.
Psycho
Establishment
Beiträge: 156
Registriert: 16.09.2002, 14:23

Re: Punkte, die mich an C++ stören

Beitrag von Psycho »

Wieso nervt dich denn genau die Aufteilung in cpp/hpp-Dateien?
Mich stört, dass ich an zwei Stellen etwas ändern muss, wenn ich beispielsweise eine Methode ändere, anstatt nur an einer.
Was genau versprichst du dir davon, wenn alles in einer Datei steckt?
Eine höhere Produktivität und eine Vereinfachung des Quelltextes. Der Translator sollte möglichst transparent im Hintergrund ablaufen, so dass ich von der Generierung der .h/.cpp-Dateien gar nichts mitbekomme. Ich sollte mir nach Möglichkeit nie die generierten Dateien angucken müssen. Das wird leider bei auftretenden Fehlern nicht vermeidbar sein, deswegen ist ein Translator an sich auch schlecht geeignet. Aber es wäre die einfachste Umsetzung. Wenn ich mit einem eigenen Compiler anfangen würde, wäre ich wohl sehr viel länger beschäftigt.
Dinge wie PIMPL könnte der Translator automatisch vornehmen, um die Compile-Zeit zu reduzieren.
Ich persönlich wäre noch mehr genervt von einer Riesendatei, die sowohl Interface als auch Implementierung enthält, und ansonsten keine Vorteile gegenüber der cpp/hpp Aufteilung bietet.
Ok, ist wohl Geschmackssache.
Im Falle der Includes kommt man noch mit dem Auflösen des Abhängigkeitenbaums/graphs aus, für andere Dinge (z.B. Erbschaftsbeziehungen) brauchst du schon fast einen vollständigen C++-Parser samt AST
So ein Mist. Ich habe mal flüchtig nach C++-Parsern gesucht, aber noch nichts brauchbares gefunden. Einige sagen, ein eindeutiger Parser für C++ sei gar nicht möglich.
Du kannst sehr wohl in C++ Garbage-Kollektoren einsetzen
Ja, das stimmt, ich mag sie nur nicht besonders.
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: Punkte, die mich an C++ stören

Beitrag von CodingCat »

Text Includes sind in der Tat mit das lästigste Erbe aus C. Zwar hat das C++-Standard-Komitee eine Arbeitsgruppe für ein neues Modulsystem eingerichtet, Text Includes sind aber so tief in C++ verwurzelt, dass das locker noch 10 Jahre dauern kann. Dass Visual Studio sich seit nunmehr über 10 Jahren weigert, vernünftige Unterstützung für Include-Dateien anzubieten, macht die Sache natürlich besonders traurig. Wie es mit anderen IDEs aussieht, weiß ich nicht.

Zum Parsen von C++ kannst du dir libclang ansehen. Einen vollständigen C++-Parser selbst zu schreiben dürfte heute in der Tat im Bereich des Unmöglichen liegen, sofern du noch vor dem Modulsystem des Standard-Komitees fertig werden willst.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
kimmi
Moderator
Beiträge: 1405
Registriert: 26.02.2009, 09:42
Echter Name: Kim Kulling
Wohnort: Luebeck
Kontaktdaten:

Re: Punkte, die mich an C++ stören

Beitrag von kimmi »

Visual Assist macht VS wesentlich bedienbarer. Geht alelrdings nicht mit der Express-Variante.

Gruß Kimmi
Helmut
Establishment
Beiträge: 237
Registriert: 11.07.2002, 15:49
Wohnort: Bonn
Kontaktdaten:

Re: Punkte, die mich an C++ stören

Beitrag von Helmut »

Psycho hat geschrieben:Ich denke über die Entwicklung des Translators nun schon einige Wochen nach und möchte ihn definitiv umsetzen. Leider stoße ich mit meinem Wissen an Grenzen, da ich (fast) keine Erfahrung mit Parsern und Lexern habe. Ein Problem ist z.B., dass in den Header natürlich nur die nötigsten Informationen sollen. D.h. nicht alle Includes, die in der Quelldatei stehen, kommen auch unbedingt in den Header. Nach Möglichkeit sollten Forward-Declarations verwendet werden. Aber um zu ermitteln, wann was verwendet werden soll oder kann, muss ich analysieren, ob eine Klasse überhaupt den vollständigen Typ kennen muss. Also muss ich prüfen, ob die Klasse von einer anderen erbt, ich muss prüfen, welche Typen die Member-Variablen haben etc.
Natürlich soll es auch normale Funktionen geben.
Eine ganz gute Idee wie ich finde. :)
Das mit dem genauen Parsen würde ich aber sein lassen. Wie wär's wenn du die Includes mit einem Schlüsselwort trennst? Zuerst kommen die Header die der erzeugte Header brauchen wird, danach die Header, die nur die Implementierung braucht.
Dein Translator könnte auch am Anfang einen Header mit allen Forward Deklarationen erzeugen, welche von allen cpp Dateien zuerst inkludiert wird. So müsste man sich dann nicht mal mehr um die kümmern.
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: Punkte, die mich an C++ stören

Beitrag von dot »

libclang wurde ja schon genannt, die solltest du dir definitiv mal anschauen... ;)
Benutzeravatar
Krishty
Establishment
Beiträge: 8245
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Punkte, die mich an C++ stören

Beitrag von Krishty »

Zwei Punkte, die das Ganze m.E. sehr schwer machen:

1. Es muss perfekt funktionieren. Du musst alle Verschwurbelungen auf Anhieb exakt so lösen, wie es der Programmierer gewünscht hat.

Kompilierfehler, weil eine __forceinline-Funktion erst nach dem ersten Aufruf kompiliert wurde? Du erwartest doch wohl nicht, dass ich das bei jedem Build von Hand korrigiere, oder?

Ein Speicherleck, weil eine globale Variable irgendwo ohne extern konvertiert wurde? Wie gebe ich überhaupt an, ob ich von meinen Definitionen statische oder externe Instanzen haben möchte? Warum soll ich debuggen, wenn dein Generator da einen Fehler macht?

Statische Initialisierungsreihenfolge durcheinander? Wie sage ich dem Generator, dass er die statischen Daten von Klasse Foo vor Bar initialisieren soll? Soll ich das bei jedem Kompilieren von Hand verschieben?

Usw usf. Für sich genommen alles lösbar; aber ich würde mir nicht zutrauen, zu behaupten, dass ich jemals für die Funktionstüchtigkeit garantieren könnte. (Wir wissen ja, wie schwer Programme für ihre Eingaben verifizierbar sind; aber Programme, die beliebige Programme als Eingabe haben?) Wenn du an einer Stelle einen Fehler machst, ist das ganze Projekt für den Anwender vergiftet.

2. Lexing und Parsing ist in Debug-Builds ein zeitfressender Brocken. Der Generator bewirkt, dass das effektiv zweimal geschehen muss (sofern du nicht direkt den Compiler mit einem Syntaxbaum (im Speicher) ansteuerst, den du beim Parsen der Ursprungsdateien angefertigt hast – mit VS unmöglich; mit Clang schon, falls du das komplette Compiler-Frontend implementierst).

Da der Generator den gleichen Funktionsumfang ausspucken soll wie Standard-C++-Quelltext, aber erstmal die Header zu dieser Standardform konvertieren muss, wird das Übersetzen zwangsläufig langsamer. In Release Builds merkt man das eh nicht, weil globale Optimierung da alle Übersetzungszeiten in den Schatten stellt – aber wenn ich schon 10 Sekunden auf einen Debug Build warten muss, wird C++ nicht unbedingt besser dadurch, dass ich nun 10 % weniger tippe und dafür 15 Sekunden warte.

2. ist zugegebenermaßen ein schwacher Einwand, weil eine Sprache niemals darauf ausgelegt werden sollte, auf aktuellen Systemen schnell zu kompilieren – darum ist diese Header-Scheiße in C ja erst entstanden. Trotzdem tauscht man hier ein Übel gegen ein anderes aus, finde ich.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Jonathan
Establishment
Beiträge: 2371
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: Punkte, die mich an C++ stören

Beitrag von Jonathan »

Ich hatte ja mal den Traum, den Code quasi im UML Diagramm zu schreiben. Man hat also keinen Texteditor mehr, sondern mehr oder weniger ein interaktives UML Diagramm. Man klickt dann beispielsweise auf eine Methode und bekommt den Code eingeblendet. Wenn irgendwo im Code eine Klasse oder Methode auftaucht, kann man drauf klicken und wird dorthin geleitet.
Intern werden dann halt cpp und hpp Dateien generiert. Der ganze Includekram wird dabei automatisch aufgelöst. Und dadurch, dass man quasi immer das UML Diagramm und die Zusammenhänge zwischen den Klassen vor Augen hat, behält man besser die Übersicht, als bei zig einzelnen Dateien.

Ja, naja, vermutlich würden damit viel zu viele fortgeschrittenen Features einfach nicht funktionieren. Aber cool wäre sowas trotzdem.
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
Benutzeravatar
Krishty
Establishment
Beiträge: 8245
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Punkte, die mich an C++ stören

Beitrag von Krishty »

Jonathan hat geschrieben:Ich hatte ja mal den Traum, den Code quasi im UML Diagramm zu schreiben.
Ich auch, aber bei mir war’s ein Alptraum.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
FredK
Beiträge: 31
Registriert: 06.05.2004, 17:11

Re: Punkte, die mich an C++ stören

Beitrag von FredK »

Das gibt es nicht nur im Traum :lol:
Guck dir mal Rhapsody vom IBM an. (gibts auch als 30 Tage testversion)
Ich wurde mal an der Uni genötigt damit nen bisschen was zu machen. Für spezielle Sachen ist das vielleicht ganz nett, aber Code direkt schreiben ist deutlich angenehmer und einfacher, da die ganzen Funktionen, um damit irgenwie produktiv sein zu können das Programm halt zwangsweise aufblähen und unübersichtlich machen.
Antworten