Forum: PC-Programmierung Funktionsbeschreibung in c oder h?


von Adam P. (adamap)


Lesenswert?

Hallo zusammen,

ich würde gerne wissen, ob es eine "Allgemein-Regel" gibt?

Als Bsp. folgende Funtion:
1
/*******************************************************************************
2
* Liefert die aktuelle Zeit/Datum.
3
*
4
* param     *time    Zeitstruktur
5
*
6
* return    bool     true   OK
7
*                    false  Fehler
8
*/
9
bool rtc_get_time(rtc_time_t *time)
10
{
11
    /* ... */
12
}

Ich war sonst immer der Meinung, diese Funktionsbeschreibung gehört in 
die *.h Datei, gedacht als Interfacebeschreibung für den Nutzer.

Nimmt man nun mal z.B. das ASF, so findet man in der *.h nur die 
Funktionsdeklaration und die Beschreibung steht in der *.c über der 
Funktionsdefinition.

Über Geschmack lässt sich ja hier gut streiten :-) aber mich würde eher 
interessieren ob etwas für oder gegen das eine oder andere spricht.

Gruß Adam

: Verschoben durch Moderator
von Seppel (Gast)


Lesenswert?

Hallo,

das Interface habe ich auch immer im Header beschrieben, hat den Vorteil 
dass wenn man ein Binary ausliefert das Header die Beschreibung hat.

Die Kommentare sehen wie Doxygen aus, aber funktioniert das so, die 
Syntax ist doch anders?

Grüße, Seppel

von Cyblord -. (cyblord)


Lesenswert?

Gehört in die Header Datei. Schon deshalb weil die lib ja auch 
kompiliert vorliegen könnte und dann gibts gar keine .c Datei.

: Bearbeitet durch User
von Adam P. (adamap)


Lesenswert?

Seppel schrieb:
> Die Kommentare sehen wie Doxygen aus, aber funktioniert das so, die
> Syntax ist doch anders?

Ja da hast du recht.
Ich hab das ein wenig umgewandelt da ich kein Doxygen nutze und es durch 
die "Steuerzeichen" eher unleserlich finde.

von M. K. (sylaina)


Lesenswert?

Hm, ich hab das bisher immer in die .c rein gepackt weil...ja weil ichs 
eben genau so auch in vielen anderen Libs gesehen habe. Macht aber im 
Prinzip schon mehr Sinn das ist die .h rein zu packen, hab da bisher nie 
drüber nachgedacht.

von Adam P. (adamap)


Lesenswert?

M. K. schrieb:
> hab da bisher nie
> drüber nachgedacht.

:-D ich denk da seid mehr als 4  Jahren drüber nach.

Hatte es auch erst immer in der *.h, dann irgendwann hab ich alles 
entfernt und in die *.c verlagert - was ja so gesehen nicht viel Sinn 
macht (obwohl es ja im µC Bereich eher selten ist, dass man Code als Lib 
bekommt).

Da ich grad ein HAL schreibe, kam der Gedanke wieder mal auf...
Also dann kommt es in die *.h.

Manchmal hab ich sogar sowas gesehen, wobei ich es dann doppelt 
gemoppelt finde:

H-Datei:
1
/*******************************************************************************
2
* Liefert die aktuelle Zeit/Datum.
3
*
4
* param     *time    Zeitstruktur
5
*
6
* return    bool     true   OK
7
*                    false  Fehler
8
*/
9
bool rtc_get_time(rtc_time_t *time);


C-Datei:
1
/*******************************************************************************
2
* Liefert die aktuelle Zeit/Datum.
3
*/
4
bool rtc_get_time(rtc_time_t *time)
5
{
6
    /* ... */
7
}

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Adam P. schrieb:
> Über Geschmack lässt sich ja hier gut streiten :-) aber mich würde eher
> interessieren ob etwas für oder gegen das eine oder andere spricht.

Ich persönlich dokumentiere die Deklaration einer Funktion (in .h), 
nicht die Definition. In einem Header erwarte ich die Deklarationen, die 
Definitionen in der Implementierungsdatei interessieren mich in der 
Regel nicht, deswegen die Wahl für den header.

Ich hatte aber auch mal einen Kunden, bei dem war es üblich, die 
Dokumentation zur Implementierung zu packen. Der Grund war, dass eine 
Änderung an der Dokumentation vorgenommen werden konnte, ohne dass 
abhängige Dateien neu übersetzt werden mussten. Bei sehr großen 
Projekten, an denen sehr viele Kollegen arbeiten, mag dass ein Argument 
sein.

von StinkyWinky (Gast)


Lesenswert?

Es ist doch ganz einfach:
- in die *.h gehört beschrieben, was gemacht wird
- in die *.c beschreibt man, wie's gemacht wird

von Yalu X. (yalu) (Moderator)


Lesenswert?

Für eine reine API-Dokumentation einer Bibliothek ist es logischer, die
entsprechenden Kommentare in die .h-Dateien zu schreiben, da genau diese
das API definieren. Deswegen mach ich das i.Allg. auch so.

Soll nicht nur das API, sondern die komplette Software dokumentiert
werden, sind davon natürlich auch modullokal verwendete Funktionen
betroffen, die in keiner .h-Datei auftauchen. In diesem Fall bleibt
nichts anderes übrig, als sie in den jeweiligen .c-Dateien zu
dokumentieren.

Manch einen stört diese Verteilung der Kommentare auf .h- und .c-Dateien
und schreibt deswegen alle Kommentare zu Funktionen in die .c-Dateien.
Ganz konsistent ist das aber auch nicht, da die Deklaration von
Datentypen oft in .h-Dateien stehen, weswegen sie nur dort dokumentiert
werden können.

Wenn ich eine Bibliothek anwende, lese ich die Dokumentation aber nicht
im Quellcode, sondern auf auf den als HTML-Seiten aufbereiteten Seiten
im Web-Browser. Da spielt es keine Rolle, ob die Kommentare in den .h
oder .c-Dateien stehen.

Torsten R. schrieb:
> Ich hatte aber auch mal einen Kunden, bei dem war es üblich, die
> Dokumentation zur Implementierung zu packen. Der Grund war, dass eine
> Änderung an der Dokumentation vorgenommen werden konnte, ohne dass
> abhängige Dateien neu übersetzt werden mussten.

Ein weiterer Grund könnte sein, dass die Motivation, Softwareänderungen
sofort zu dokumentieren, steigt, wenn die entsprechenden Kommentare
dort liegen, wo auch die Änderungen gemacht werden. Muss man dazu immer
erst von der .c- zur .h-Datei und wieder zurück wechseln, besteht die
Gefahr, dass die Aktualisierung der Dokumentation auf später
aufgeschoben, d.h. evtl. vergessen wird.

Aus den genannten Gründen ist es schwierig, ein Patentrezept für die
Dokumentation anzugeben.


StinkyWinky schrieb:
> Es ist doch ganz einfach:
> - in die *.h gehört beschrieben, was gemacht wird
> - in die *.c beschreibt man, wie's gemacht wird

Ja, das ist noch ein weitere Aspekt.

von A. S. (Gast)


Lesenswert?

Mit doxygen und co gehört es in die c-datei, da es da weniger stört und 
näher am beschriebenen ist.

In die h nur, wenn es die API einer lib ohne Quelltext ist. Und wenn die 
API sonst nicht beschrieben ist.

Nichts ist schlimmer, als 20 Zeilen Laberkommentar zwischen 2 
enum-elementen, so dass keine 3 auf einmal erfasst, geschweige denn 
gezählt werden können.

von Jan (Gast)


Lesenswert?

Wenn Doxygen benutzt wird, kommen ja häufig auch noch Beispiele und 
tiefergreifende Beschreibungen hinzu. Die sollten ganz klar in die .c. 
Beim Generieren der Doku guckt Doxygen nämlich in die Header und die 
Sourcen und packt alles schön zusammen.
Der Header sollte mMn. möglichst übersichtlich sein, von mir aus also 
auch mit Doxygen dokumentiert, aber dann nur Kurzbeschreibung und 
input/output Parameter.

von Walter T. (nicolas)


Lesenswert?

Früher .h, heute .c. Grund: Eine Beschreibung, die umittelbar über dem 
Quelltext steht, hat eine größere Chance, über längere Zeit noch dem zu 
entsprechen, was der Quelltext macht.

von Rolf M. (rmagnus)


Lesenswert?

Adam P. schrieb:
> Seppel schrieb:
>> Die Kommentare sehen wie Doxygen aus, aber funktioniert das so, die
>> Syntax ist doch anders?
>
> Ja da hast du recht.
> Ich hab das ein wenig umgewandelt da ich kein Doxygen nutze und es durch
> die "Steuerzeichen" eher unleserlich finde.

Naja, die Idee von Doxygen ist ja, dass man damit eine Doku generiert, 
die nochmal deutlich leserlicher als die Kommentare im Quelltext sind.
Und ob da jetzt return oder @return steht, macht in meinen Augen auch 
keinen gravierenden Unterschied.

A. S. schrieb:
> Mit doxygen und co gehört es in die c-datei, da es da weniger stört und
> näher am beschriebenen ist.
>
> In die h nur, wenn es die API einer lib ohne Quelltext ist. Und wenn die
> API sonst nicht beschrieben ist.
>
> Nichts ist schlimmer, als 20 Zeilen Laberkommentar zwischen 2
> enum-elementen, so dass keine 3 auf einmal erfasst, geschweige denn
> gezählt werden können.

Und wie machst du deine Doxygen-Kommentare im C-File für den Enum, der 
im Header definiert ist? Und inwiefern sind sie dann "näher am 
beschriebenen"?

: Bearbeitet durch User
von x^y (Gast)


Lesenswert?

Adam P. schrieb:
> Über Geschmack lässt sich ja hier gut streiten :-) aber mich würde eher
> interessieren ob etwas für oder gegen das eine oder andere spricht.

Die Frage hat gewissen Religionsfaktor .-)

Bei mir ist's so: Ich kommentiere alle extern Funktionen und extern 
sichtbaren Datenstrukturen im .h und nur die statischen Funktionen, 
statische Variablen und private Datenstrukturen im .c File.

Hauptgrund dafür wurde bereits genannt:

Cyblord -. schrieb:
> Gehört in die Header Datei. Schon deshalb weil die lib ja auch
> kompiliert vorliegen könnte und dann gibts gar keine .c Datei.

Es gibt noch einen Grund mehr:

Ich entwickle Module i.d.R. so, dass zunächst die Schnittstelle 
definiert wird. Das bedeutet konkret erst die Prototypen und 
Datenstrukturen aller Funktionen wie sie für ein Modul nach außen 
zugreifbar bzw. sichtbar sein werden. Bei der Gelegenheit entsteht die 
Dokumentation für diese Funktionen und Strukturen. Man merkt dabei 
welche Parameter man noch benötigt, welche evtl. unnötig sind, wie die 
Funktionen zusammenspielen, welche Abhängigkeiten und Sonderfälle 
existieren, wie's evtl. besser/einfacher/schöner geht usw. Man nimmt bei 
dieser Sichtweise die Nutzersicht des späteren Moduls ein (der man im 
Zweifel selbst ist, und man möchte es ja später schön komfortabel 
haben). Lange Rede: Während man auf dieser Ebene arbeitet gibt es 
logischerweise noch gar kein .c File wohin man Dokumentation packen 
könnte.

von Sven P. (Gast)


Lesenswert?

Ich pack mittlerweile alles in die C-Quelldateien.

Gründe:
- Es liest eh keiner mehr in den Headern nach. Dafür gibt es mit qdoc 
oder doxygen erzeugte Referenzen.
- Es laufen nicht bei jedem Compile-Vorgang Megabytes an nutzlosen 
Kommentaren durch den Compiler. Das mag sich komisch anhören, aber bei 
nennenswert großen Projekten mit großen Bibliotheken (Qt etwa) kann das 
schon deutlich in die Compile-Zeit einschlagen.
- Der Kommentar direkt vor der Funktion kann komfortabel mit der 
Funktion verglichen werden. Aufteilen auf C- und H-Datei führt kurz über 
lang irgendwie immer dazu, dass man entweder alles doppelt hat oder 
eines von beiden irgendwann abgehangen wird.

Und, seit ich mich auf knackige Kommentare und qdoc beschränke, und 
nicht mehr vor jede Funktion eine Kommentarvorlage setze und ausfülle, 
ist meine Produktivität und Motivation gestiegen.
Und vorallem die Qualität der Dokumentation.

Das ist übrigens etwas, was ich bei Qt ziemlich motivierend finde. Von 
früher her kenne ich noch besagte elendige Kommentarvorlagen:
1
/*
2
* Funktion:
3
*   bla bla
4
*
5
* Parameter:
6
*   Typ    in|out   Beschreibung
7
*
8
* Rückgabe:
9
*
10
* Abhängigkeiten:
11
*
12
*/

Bei Qt ist das ziemlich krass anders, denn dort werden selbst Parameter 
knapp im Fließtext beschrieben:
1
/*!
2
    Returns model data for the given \a index and \a role.
3
4
    \sa setData(), Column
5
*/
6
QVariant data(const QModelIndex &index, int role) const
7
{
8
...
9
}

Das ist so unendlich bequemer und prägnanter.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.