Hi!
Ich suche nach Informationen oder Erfahrungen von Entwicklern, wie man am besten Sourcecode (speziell C++) kommentieren sollte, damit die Kommentare einheitlich und gut verarbeitbar sind. Gibt es (Quasi-)Standards?
Ich meine Beschreibung von Klassen, Membern, Methoden und Variablen im Code. Sie sollen sich zur Erstellung einer (Klassen-/Funktions-)Referenz eignen. Schön wäre auch die Nutzung in einer IDE zur Unterstützung bei der Programmierung.
Ich habe etwas mit Javadoc bzw. dem Tool doxygen gespielt und die Möglichkeiten gefallen mir schon gut. (kdoc und doc++ wollte den Code nicht akzeptieren)
Wie sollte man solche Kommentare am besten einbauen? Wie detailliert sollten sie sein? - Javadoc-Syntax? (Vorteil: Quasi-Standard, aber Javadoc für C++-Code? ;-) - eine Variante, die Tool XYZ verwendet? (Nachteil: evtl. nicht von anderen Tools verarbeitbar) - In welche Dateien gehören diese Kommentare? *.cxx oder *.hh?
Ich bin auf Hinweise bzw. Erfahrungen aus der Praxis gespannt.
Freundlich grüßend, Erik
Am Samstag, 11. Dezember 2004 17:13 schrieb Erik Schanze:
Ich habe etwas mit Javadoc bzw. dem Tool doxygen gespielt und die Möglichkeiten gefallen mir schon gut. (kdoc und doc++ wollte den Code nicht akzeptieren)
Kdoc wurde gebaut, als doxygen noch nicht mit Signals/Slots von Qt umgehen konnte, und auch so noch in den Kinderschuhen steckte. Mittlerweile verwendet aber selbst KDE doxygen, und kdoc sollte begraben werden.
Wie sollte man solche Kommentare am besten einbauen? Wie detailliert sollten sie sein?
- Javadoc-Syntax? (Vorteil: Quasi-Standard, aber Javadoc für C++-Code? ;-)
- eine Variante, die Tool XYZ verwendet? (Nachteil: evtl. nicht von anderen Tools verarbeitbar)
Javadoc und Doxygen sollten miteinander verträglich sein. Ich denke, daß doxygen heutzutage Standard ist. Es ist außerdem sehr mächtig, d.h. man kann (wenn man möchte) eigene Makros definieren (z.B. \maintainer zusätzlich zu \author).
- In welche Dateien gehören diese Kommentare? *.cxx oder *.hh?
Ich würde sie immer in die Header reinnehmen. Diese sind ja sowieso immer installiert, während die Sourcen einer Bibliothek meist nicht dazugehören. Für die Doku selbst ist das egal (z.B. Qt ist im Source dokumentiert), aber wer wie ich gern mal per 'grep' durch die Header geht, wird erstere Methode zu schätzen wissen.
Doku ist ja größtenteils für andere gedacht, abgesehen von einer Gedächtnisstütze für sich selbst. Von daher sollte das Ausgabeformat dann auch immer so gebaut sein, daß es mit ähnlichen Projekten übereinstimmt. Also KDE-Dokus im Stil der kdelibs-HTML-Seiten, Java-Dokus im Still der Javadoc-Klassendokus etc. Gtk+/GNOME verwendet docbook-to-html, welches den SGML-Stil 'gtk' kennt, der auch so recht hübsch (und schlicht) aussieht.
Doxygen kann darüberhinaus auch manpages generieren, was nicht sehr übersichtlich aussieht, aber auch von mir häufig verwendet wird (man foo_h). Erspart den Griff zum Browser...
Josef
On Sat, Dec 11, 2004 at 05:13:30PM +0100, Erik Schanze wrote:
Hi!
Hi Erik,
Wie sollte man solche Kommentare am besten einbauen?
Ich persönlich bevorzuge Doxygen für C++.
Wie detailliert sollten sie sein?
Es sollte eine generelle Beschreibung der Klasse geben, dann eine Beschreibung für jede öffentliche Methode in der der Funktionsumfang und die Eigenheiten erwähnt werden.
Bei der API von Bibliotheken sollten immer Beispiele aufgeführt sein, wie man die API am besten verwendet.
- In welche Dateien gehören diese Kommentare? *.cxx oder *.hh?
IMHO in den Header, da man so auch ohne den Quelltext nachlesen kann was die Klassen/Methoden anbieten.
Ciao, Tobias
On Sat, 2004-12-11 at 17:13 +0100, Erik Schanze wrote:
Ich suche nach Informationen oder Erfahrungen von Entwicklern, wie man am besten Sourcecode (speziell C++) kommentieren sollte, damit die Kommentare einheitlich und gut verarbeitbar sind. Gibt es (Quasi-)Standards?
Wenn man sich so umsieht, scheint sich doxygen zum Quasistandard gemausert zu haben. Und das nicht umsonst, denn es ist wirklich sehr flexibel. Wir benutzen es z.B. zum generieren von HTML für das Entwicklerteam und zum genererien von PDF (über Latex) für die Akten (TÜV z.B.). Doxygen hat außerdem den Vorteil, daß es alle wesentlichen Markup-Typen unterstützt. Das ist nützlich, wenn man bereits kommentierten Code hat. Speziell unterstützt es doc++, Javadoc und kdoc. C#-Kommentare (XML) sollen wohl bald folgen. Wenn man sich einen dieser Stile herauspickt, kann man später auch zu dem entsprechenden Tool wechseln.
Was den Kommentierstil angeht, habe ich immer folgende Empfehlung parat: Normale Quellcodekommentare immer mit "//" einleiten, damit man beim Debugging größere Quellcodeteile mittels "/* */" auskommentieren kann. Ausnahme: die doxygen-Kommentare, da die meistens etwas länger sind und sowieso außerhalb der Methoden stehen. Kommentiere innerhalb der Methoden, WARUM Du etwas tust, nicht WAS Du tust. Wer sich in die Tiefen der Quellen vorwagt, wird das WAS sehen. Das WARUM aber erfordert Wissen um den Kontext, welches beim Betrachter in dem Ausmaß evtl. nicht vorhanden ist. Beispiel:
++i; // inkrementiere den Zähler [Ach nee...]
myWidget->SetCaption(dbConnection->getCurrentValue(3)); // stelle den Kundennamen im Textfeld dar
Im ersten Fall erzeugst Du nur Rauschen, im zweiten Fall ist das Wissen um die Datenbankstruktur erforderlich. Durch den Kommentar erkennt der Nutzer was da passiert, ohne daß er kompliziert ausknobeln muß, was denn Wert 3 in der Datenbank ist.
Genug doziert, HTH, Eric
Hallo,
Am Sonntag, 12. Dezember 2004 23:59, schrieb Eric Schaefer:
On Sat, 2004-12-11 at 17:13 +0100, Erik Schanze wrote:
Ich suche nach Informationen oder Erfahrungen von Entwicklern, wie man am besten Sourcecode (speziell C++) kommentieren sollte, damit die Kommentare einheitlich und gut verarbeitbar sind. Gibt es (Quasi-)Standards?
<schnipp>
Kommentiere innerhalb der Methoden, WARUM Du etwas tust, nicht WAS Du tust. Wer sich in die Tiefen der Quellen vorwagt, wird das WAS sehen. Das WARUM aber erfordert Wissen um den Kontext, welches beim Betrachter in dem Ausmaß evtl. nicht vorhanden ist. Beispiel:
++i; // inkrementiere den Zähler [Ach nee...]
myWidget->SetCaption(dbConnection->getCurrentValue(3)); // stelle den Kundennamen im Textfeld dar
Im ersten Fall erzeugst Du nur Rauschen, im zweiten Fall ist das Wissen um die Datenbankstruktur erforderlich. Durch den Kommentar erkennt der Nutzer was da passiert, ohne daß er kompliziert ausknobeln muß, was denn Wert 3 in der Datenbank ist.
Folgendes komplett meine humble opinion:
Hm, da hätte ich noch einen Verbesserungsvorschlag: #define CustomerNameId 3 oder enum { CustomerNameId = 3 }; oder static const int CustomerNameId = 3 ; an geeigneter Stelle, damit hat man sowohl ein wenig mehr selbstdokumentierenden Quellcode, z.B. myWidget->SetCaption(dbConnection->getCurrentValue(CustomerNameId)); als auch, wie hoffentlich bekannt, weniger Probleme, sollte sich die 3 mal zur 4 wandeln :) Kommt "dbConnection->getCurrentValue(CustomerNameId)" häufiger vor, vielleicht in eine kleine inline-Funktion "customerName(dbConnection)" auslagern, senkt sowohl Fehleranfälligkeit als auch Code-Lesedauer: myWidget->SetCaption(customerName(dbConnection));
Kernaussage: Vor allem auf selbstdokumentierenden Code achten, spart Dir sowohl Kommentare (den man ja bei jeder Codeänderung immer mit ändern muß, also doppelte Arbeit hat, wird gerne vergessen, und falsche Kommentare sind schlechter als keine), hilft Dir aber auch selbst, den eigentlichen Code zu überblicken und im Griff zu behalten.
Persönlich kapsele ich auch gerne einfache Datentypen in Strukturen oder Klassen (alternativ typedef, #define & Co.), denn ich finde if( Values.includes(Othervalue) ) lesbarer, weniger fehleranfällig und weniger nach Kommentar bittend als if( Value1 <= Othervalue && Value2 >= Othervalue ) Der Sinn lokaler Variablen wird auch schneller deutlich, wenn die Einheiten im Typnamen (mind. per typedef) eingearbeitet sind. Vergleiche FMeter Distance; und float Distance;
Wenn Du die Bedeutung einer Variablen erklären mußt, solltest Du den Namen der Variablen auch noch einmal überdenken.
Wichtige Kommentare sind IMHO vor allem welche zu Randbedingungen, z.B. default-Werte oder garantiertes Verhalten von Funktionen/Codeabschnitten. Aber vermutlich verlasse ich gerade das Thema Deiner Anfrage?
Gruß Friedrich
PS: "TODO" scheint ein anerkanntes Kennwort zu sein, das von vielen IDEs erkannt und deren nachfolgende Texte automatisch in eine Übersichtsliste extrahiert werden, z.B. // TODO: in eigene Funktion auslagern und mit X zusammenfassen
On Mon, 2004-12-13 at 12:19 +0100, Friedrich W. H. Kossebau wrote:
Hm, da hätte ich noch einen Verbesserungsvorschlag: #define CustomerNameId 3 oder enum { CustomerNameId = 3 }; oder static const int CustomerNameId = 3 ;
Enums haben den Vorteil, daß viele Debugger dann als Variablenwert "CustomerNameId" statt nur "3" stehen haben. #define für Konstanten und Makros sollte generell vermieden werden. Die Benutzung desselben ist ein guter Indikator für suboptimales Design.
Persönlich kapsele ich auch gerne einfache Datentypen in Strukturen oder Klassen (alternativ typedef, #define & Co.), denn ich finde if( Values.includes(Othervalue) ) lesbarer, weniger fehleranfällig und weniger nach Kommentar bittend als if( Value1 <= Othervalue && Value2 >= Othervalue ) Der Sinn lokaler Variablen wird auch schneller deutlich, wenn die Einheiten im Typnamen (mind. per typedef) eingearbeitet sind. Vergleiche FMeter Distance; und float Distance;
Meistens ist es auch so, daß die Werte andere Grenzen haben, als die eingebauten Datentypen. Über entsprechende Zugriffsmethoden kann man den Wertebereich prüfen und gegebenenfalls mit Exceptions um sich werfen.
Wenn Du die Bedeutung einer Variablen erklären mußt, solltest Du den Namen der Variablen auch noch einmal überdenken.
In Zeiten von Copy&Paste sind abgekürzte Variablennamen (vom unvermeidbaren i mal abgesehen) sowieso Quatsch.
Wichtige Kommentare sind IMHO vor allem welche zu Randbedingungen, z.B. default-Werte oder garantiertes Verhalten von Funktionen/Codeabschnitten.
+ preconditions + postconditions
Aber vermutlich verlasse ich gerade das Thema Deiner Anfrage?
<AOL/>
PS: "TODO" scheint ein anerkanntes Kennwort zu sein, das von vielen IDEs erkannt und deren nachfolgende Texte automatisch in eine Übersichtsliste extrahiert werden, z.B. // TODO: in eigene Funktion auslagern und mit X zusammenfassen
Mit IDEs kann man sehr viele produktivitätssteigernde Dinge anstellen, aber leider sind sie entweder auch nicht besser als vi+make oder sie sind umfangreich, bequem, schnarchlangsam und bloated. Außerdem sind die eingebauten Editoren meist eine Zumutung. Ich wollte mir neulich mal Anjuta antun, aber das erzeugt ja für ein Commandline-Executable-Projekt schon 40 Dateien und die lassen sich auch nicht mal eben so kompilieren. Den Fehler im Makefile kann man auch nicht ohne Kenntnisse von autoconf (oder was auch immer) beheben, denn es umfaßt schlappe 380 Zeilen. Die Entwickler von dem Teil müssen wirklich extremes Kraut rauchen... An und für sich sieht das Teil ja ganz nett aus, aber man müßte diesen autoconf-Mist abwählen können.
Eric
Eric Schaefer wrote:
Mit IDEs kann man sehr viele produktivitätssteigernde Dinge anstellen, aber leider sind sie entweder auch nicht besser als vi+make oder sie sind umfangreich, bequem, schnarchlangsam und bloated. Außerdem sind die eingebauten Editoren meist eine Zumutung. Ich wollte mir neulich mal Anjuta antun, aber das erzeugt ja für ein Commandline-Executable-Projekt schon 40 Dateien und die lassen sich auch nicht mal eben so kompilieren. Den Fehler im Makefile kann man auch nicht ohne Kenntnisse von autoconf (oder was auch immer) beheben, denn es umfaßt schlappe 380 Zeilen. Die Entwickler von dem Teil müssen wirklich extremes Kraut rauchen... An und für sich sieht das Teil ja ganz nett aus, aber man müßte diesen autoconf-Mist abwählen können.
Das Autoconf-Zeug stört mich auch immer. Inzwischen bin ich bei Anjuta gelandet, da man damit auch ohne eigenes "Projekt" Quelltext öffnen kann. Ich erinner mich vor Jahren mal so eine RedHat-IDE genutzt zu haben, die eigentlich einen recht schlanken Eindruck gemacht hat. Aber der Name ist mir entfallen...
Ansonsten vielleicht mal wieder XEmacs ausprobieren? Kann der auch so tolle grafische Dinge wie Klassen visualisieren oder Hints bei Funktionsparametern geben?
Gruß, Stephan.
Am Montag, 13. Dezember 2004 18:45, schrieb Eric Schaefer:
On Mon, 2004-12-13 at 12:19 +0100, Friedrich W. H. Kossebau wrote: #define für Konstanten und Makros sollte generell vermieden werden. Die Benutzung desselben ist ein guter Indikator für suboptimales Design.
Bzw. verwerfen den Vorteil der Typprüfung durch den Compiler bei C++. (Variante hatte ich auch nur für die C-Nutzer angeführt, natürlich ;)
Persönlich kapsele ich auch gerne einfache Datentypen in Strukturen oder Klassen (alternativ typedef, #define & Co.), denn ich finde if( Values.includes(Othervalue) ) lesbarer, weniger fehleranfällig und weniger nach Kommentar bittend als if( Value1 <= Othervalue && Value2 >= Othervalue ) Der Sinn lokaler Variablen wird auch schneller deutlich, wenn die Einheiten im Typnamen (mind. per typedef) eingearbeitet sind. Vergleiche FMeter Distance; und float Distance;
Meistens ist es auch so, daß die Werte andere Grenzen haben, als die eingebauten Datentypen. Über entsprechende Zugriffsmethoden kann man den Wertebereich prüfen und gegebenenfalls mit Exceptions um sich werfen.
Genau. :)
Wenn Du die Bedeutung einer Variablen erklären mußt, solltest Du den Namen der Variablen auch noch einmal überdenken.
In Zeiten von Copy&Paste sind abgekürzte Variablennamen (vom unvermeidbaren i mal abgesehen) sowieso Quatsch.
Kommt auf den Geltungsbereich an. "VariableIDidNotFindAShortAndPreciseNameFor" erschlägt dann vielleicht doch, wenn es nur 15-20 Zeilen Geltungsbereich sind, nehme ich gerne auch mal ne Abkürzung.
Aber vermutlich verlasse ich gerade das Thema Deiner Anfrage?
<AOL/>
Was bedeutet eigentlich dieses AOL? Gibt es irgendwo im Netz eine anerkannte Liste mit den gängigen Netz-Abkürzungen?
PS: "TODO" scheint ein anerkanntes Kennwort zu sein, das von vielen IDEs erkannt und deren nachfolgende Texte automatisch in eine Übersichtsliste extrahiert werden, z.B. // TODO: in eigene Funktion auslagern und mit X zusammenfassen
Mit IDEs kann man sehr viele produktivitätssteigernde Dinge anstellen, aber leider sind sie entweder auch nicht besser als vi+make oder sie sind umfangreich, bequem, schnarchlangsam und bloated. Außerdem sind die eingebauten Editoren meist eine Zumutung. Ich wollte mir neulich mal Anjuta antun, aber das erzeugt ja für ein Commandline-Executable-Projekt schon 40 Dateien und die lassen sich auch nicht mal eben so kompilieren. Den Fehler im Makefile kann man auch nicht ohne Kenntnisse von autoconf (oder was auch immer) beheben, denn es umfaßt schlappe 380 Zeilen. Die Entwickler von dem Teil müssen wirklich extremes Kraut rauchen...
Vielleicht klappte es mit dem Kompilieren deswegen nicht? ;)
Die Makefiles werden bei dem auto*-Krams übrigens aus kleineren Dateien (*.in & Co.) erzeugt, die sind dann schon übersichtlicher und handlicher (relativ). Wenn man dort mal reinschaut, kann man oft auch durch "Vergleichende Studien" Fehler beheben.
An und für sich sieht das Teil ja ganz nett aus, aber man müßte diesen autoconf-Mist abwählen können.
Bei KDevelop kann man sich das Makesystem mittlerweile aussuchen... :)
Gruß Friedrich
On Tue, Dec 14, 2004 at 12:11:49AM +0100, Friedrich W. H. Kossebau wrote:
Am Montag, 13. Dezember 2004 18:45, schrieb Eric Schaefer:
Hi Friedrich,
Aber vermutlich verlasse ich gerade das Thema Deiner Anfrage?
<AOL/>
Was bedeutet eigentlich dieses AOL?
AOL bedeutet so viel wie 'Me too!', da die ganzen AOL-Daus (sorry wenn ich hier jemanden auf die Füße trete), statt einen sinnvollen Kommentar immer nur 'Me too' von sich geben.
Gibt es irgendwo im Netz eine anerkannte Liste mit den gängigen Netz-Abkürzungen?
Das jargon file (apt-get install jargon ;)) beinhaltet die meisten gängigen Abkürzungen.
Ciao, Tobias
On 14.12.04 Tobias Koenig (tokoe@kde.org) wrote:
On Tue, Dec 14, 2004 at 12:11:49AM +0100, Friedrich W. H. Kossebau wrote:
Am Montag, 13. Dezember 2004 18:45, schrieb Eric Schaefer:
Hi,
<AOL/>
Was bedeutet eigentlich dieses AOL?
AOL bedeutet so viel wie 'Me too!', da die ganzen AOL-Daus (sorry wenn ich hier jemanden auf die Füße trete), statt einen sinnvollen Kommentar immer nur 'Me too' von sich geben.
....nach einem Fullquote eines per uuencode geposteten Binaries.
H.
Eric Schaefer schrieb:
Mit IDEs kann man sehr viele produktivitätssteigernde Dinge anstellen, aber leider sind sie entweder auch nicht besser als vi+make oder sie sind umfangreich, bequem, schnarchlangsam und bloated. Außerdem sind die
eingebauten Editoren meist eine Zumutung. Ich wollte mir neulich mal Anjuta antun, aber das erzeugt ja für ein Commandline-Executable-Projekt schon 40 Dateien und die lassen sich auch nicht mal eben so kompilieren. Den Fehler im Makefile kann man auch nicht ohne Kenntnisse von autoconf (oder was auch immer) beheben, denn es umfaßt schlappe 380 Zeilen. Die Entwickler von dem Teil müssen wirklich extremes Kraut rauchen... An und für sich sieht das Teil ja ganz nett aus, aber man müßte diesen autoconf-Mist abwählen können.
Den ganzen autoconf-Kram bekommst du nicht, wenn du beim Erstellen des Projekts das Häkchen vor "Autoconf-Support" wegmachst. Ein "Custom Make Command" kannst du auch einstellen (und deine Makefiles selber bauen) und weiter den Komfort von Tastenkombination und Fehler-Highlighting nutzen.
Wenn dein Projekt jetzt schon existiert dann wirf mal einen Blick in die Projekt Optionen. Sollte man Autoconf nicht mehr im Nachhinein wegbekommen, dann kopier deine Quellen in ein neues Verzeichnis und wähle 'Datei|Projekt importieren' (und eliminiere dort das betreffende Häkchen).
mfg, Fabian
On Wed, 2004-12-15 at 15:35 +0100, Fabian Hänsel wrote:
Den ganzen autoconf-Kram bekommst du nicht, wenn du beim Erstellen des Projekts das Häkchen vor "Autoconf-Support" wegmachst. Ein "Custom Make Command" kannst du auch einstellen (und deine Makefiles selber bauen) und weiter den Komfort von Tastenkombination und Fehler-Highlighting nutzen.
Bei mir gibt es kein Häkchen. Zumindestens nicht zum Abwählen des Autoconf-Support (Anjuta 1.2.2). Wo soll das denn vorkommen?
Eric
lug-dd@mailman.schlittermann.de