関数をヘッダーファイルまたはソースファイルに文書化する方が良いでしょうか?


86

「ソース」ファイルと「ヘッダー」ファイル(主にCとC ++)を区別する言語では、ヘッダーファイルに関数を文書化する方が適切です。

(CCANから盗用

/**
 * time_now - return the current time
 *
 * Example:
 *  printf("Now is %lu seconds since epoch\n", (long)time_now().tv_sec);
 */
struct timeval time_now(void);

またはソースファイルで?

(PostgreSQLから盗用)

/*
 * Convert a UTF-8 character to a Unicode code point.
 * This is a one-character version of pg_utf2wchar_with_len.
 *
 * No error checks here, c must point to a long-enough string.
 */
pg_wchar
utf8_to_unicode(const unsigned char *c)
{
...

構造体、マクロ、static inline関数など、ヘッダーのみで定義されているものがあることに注意してください。私は、ヘッダーファイルで宣言れ、ソースファイルで定義されているものについてのみ話している。

ここに私が考えることができるいくつかの議論があります。私はソースファイルに文書化することに傾いているので、「プロヘッダー」引数はやや弱いかもしれません。

プロヘッダー:

  • ユーザーは、ドキュメントを見るためにソースコードを必要としません。
    • ソースを取得するのは不便であるか、不可能でさえあります。
    • これにより、インターフェースと実装がさらに分離されます。

プロソース:

  • ヘッダーが大幅に短くなり、読者にモジュール全体の鳥瞰図が提供されます。
  • 関数のドキュメンテーションとその実装を組み合わせて、関数が言っていることを関数が実行していることを見やすくします。

答えるときは、ツールと「最新のIDE」ができることに基づいて議論に注意してください。例:

  • プロヘッダー:コードを折りたたむと、コメントを非表示にすることでコメント付きヘッダーをよりナビゲートしやすくすることができます。
  • プロソース:cscopeFind this global definition機能は、ヘッダーファイル(宣言がある)ではなく、ソースファイル(定義がある)に移動します。

私はそのような議論をしないと言っているわけではありませんが、誰もがあなたが使用しているツールと同じくらい快適ではないことを覚えておいてください。


同じ質問がPascal / Delphiにも当てはまります。Pascal/ Delphiでは、ソースファイルとヘッダーファイルはありませんが、インターフェイスと実装セクションがあります。
ヤンDoggen

回答:


96

私の見解...

  • 関数の使用方法をヘッダーファイルで、またはより正確に宣言の近くで文書化します。

  • 関数がどのように機能するか(コードから明らかでない場合)をソースファイルに、より正確には定義の近くに文書化します。

ヘッダー内の鳥の目については、必ずしも閉じるドキュメントは必要ありません-宣言のグループを一度にドキュメント化できます。

大まかに言って、呼び出し元はエラーと例外(抽象化層を伝搬するときに翻訳できる場合のみ)に関心を持つ必要があるため、これらは関連する宣言の近くで文書化する必要があります。


13
+1-つまり、ヘッダーにインターフェースを文書化します。ソース内の方法と理由のGoryの詳細。
すぐに

2
利用可能なソースがないライブラリヘッダーの場合は、事前条件と事後条件などを追加して、テストを支援します。さらに、理にかなっている場合はO(n)パフォーマンスを追加して、ライブラリユーザーが賢明に選択できるようにします。
パトリックヒューズ

当然、宣言と定義がまったく同じ場合もあります。
デュプリケータ

@Deduplicator-特別な場合でも同じルールが正しいことになるのに、なぜすべての特別なケースでそれらのルールをエコーするのですか?確かに、重複排除者はそれを望まないでしょうか?
Steve314

1
@Deduplicator-もちろん、それはあなたのアドバイスに従わないことに対する大いに考え直された根拠ですが、私はそれに固執しています。
Steve314

34

Doxygenなどのツールを使用する場合(最初の例では、で始まるためDoxygenのコメントのように見えます/**)、それは実際には重要ではありません-Doxygenはヘッダーとソースファイルを調べて見つけますドキュメントを生成するためのすべてのコメント。

ただし、宣言があるヘッダーにドキュメンテーションコメントを入れたいと思います。クライアントはヘッダーを処理してソフトウェアとインターフェイスします。ヘッダーは、独自のソースファイルに含まれるものであり、APIがどのように見えるかを最初に確認する場所です。

たとえば、ほとんどのLinuxライブラリを見ると、Linuxパッケージ管理システムには多くの場合、ライブラリのバイナリのみを含むパッケージ(ライブラリを必要とするプログラムを持っている「通常の」ユーザー向け)があり、「dev」パッケージがあります。ライブラリのヘッダーが含まれています。通常、ソースコードはパッケージで直接提供されません。APIのドキュメントを取得するためにライブラリのソースコードを取得する必要がある場合は、非常に面倒です。


2
+1-Doxygenを使用していても、ソースから直接読み取らないという意味ではありません。Doxygenアノテーションは、grepの標準パターンとしても役立つ場合があり、見つけたアノテーションが記述したコードに近い場合に便利です。
Steve314

1
@ Steve314 ofcourseライブラリのソースコードを見たくないとは言いませんでしたが、APIがどのようなもので、どのように使用するかを探す最初の場所ではありません。
ジェスパー

また、APIに関連するすべてのものをヘッダー(または少なくともヘッダーまたはソースのいずれか)に保持することを推奨します。これは、ドキュメントを1か所ではなく他の場所で更新する際の不整合を回避するためです。
jopasserat

12

ソースファイルで使用でき、awkスクリプト(ホラー)でスキャンできる#defines(たとえば、<nothing>に解決される)の束を作成することで、この問題を解決しました(約25年前)。 !).hファイルを自動生成します。これは、すべてのコメントがソースに存在し、(必要に応じて)生成された.hファイルにコピーされたことを意味します。私はそれがかなり古い学校であることを知っていますが、この種のインラインドキュメントを大幅に簡素化しました。


1
うーん、私はこのスタイルのスタイルが役立つことを知っていますが、私の観点から私はいつもその種のドキュメントが実にうっとうしいものだと
感じました...-osirisgothra

1
ドナルド・ラムズフェルド(私は好きではなかった男)を言い換えると、「あなたはあなたが欲しかったツールではなく、あなたが持っているツールでプログラムします」。私が過去40年以上にわたって取り組んできたすべての言語には、少なくとも1つの大きないぼがありました(それ以上ではないにしても)。私たちのソリューションは、a)機能し、b)その時点で存在していたツールを使用し、c)収益を生み出すコードを世に出すことに時間を費やしましょう。
ピーターローウェル

私はおそらくこれを選択しませんが、ヘッダー内のコメントを処理する興味深い方法です。生成されたヘッダーはバージョン管理されますか?または、これは再配布可能なソースを作成するためのリリースプロセスですか?(ただし、開発者は使用しません)
-ideasman42

ああ、私は最近、2000年以上に開始されたプロジェクトで同じパターンを見ました。彼らは彼らの巧妙な発明をとても誇りに思っていました…
5gon12eder

3
私たちの場合、生成されたファイルは追跡されたファイルから簡単かつ直接(再)派生されるため、バージョン管理下に置かれませんでした。
ピーターローウェル

9

これがより大きなプロジェクト内のコード(開発者がソースとヘッダーの間を頻繁に移動する場合)であり、これライブラリ/ミドルウェアではなく、他の人がソースにアクセスできない可能性があると仮定すると、この作品が見つかりましたベスト...

  • ヘッダー:
    簡潔な1-2行のコメント。必要な場合のみ。
    関連する関数のグループの上のコメントも役立つ場合があります。
  • 出典:
    関数のすぐ上のAPIに関するドキュメント(プレーンテキストまたは必要に応じてdoxygen)
  • 関数本体のコードを変更する開発者にのみ関連する実装の詳細を保持します。

これの主な理由は、コメントをコードの近くに保つためです。ヘッダーのドキュメントは、コードの変更と同期しなくなる傾向があることに気付きました(もちろん、そうすべきではありませんが、私たちのプロジェクトではそうしました)少なくとも)。また、開発者は、ヘッダードキュメントがある場合でも、何らかの変更を行うときに、ドキュメントを他の場所に追加する場合があります。doc-stringsの1つにのみ存在するダブルアップまたは有用な情報を引き起こします。

もちろん、規約を選択してすべての開発者がフォローするようにすることができます。規約を最も自然に適合させ、メンテナンスの手間を最小限に抑えることができました。


最後に、大規模なプロジェクトの場合- 他の人がバージョン管理を更新するときに、数百または数千のファイルが再コンパイルされる可能性があることがわかっている場合、ヘッダーに小さな修正を加えない傾向があります-二分エラーも遅くなります。


5

私の(むしろ限定的で偏った)意見では、私はプロソースコードの考え方です。C ++で細工するときは、通常、ヘッダーファイルを1回編集してから、実際に戻って確認することはありません。

ソースファイルにドキュメントを配置すると、コードの編集中または読み取り中にドキュメントが常に表示されます。私はそれが習慣のことだと思います。

しかし、それは私だけです...


1
コンパイルされたライブラリとヘッダーファイルしか持っていない場合、あまりうまく機能しません。その場合、ヘッダーにある情報はあなたが持っている唯一のインターフェース文書であるため、良い情報です。
すぐに

doxygenを使用してドキュメントを生成できます-.cファイルからも取得できます。したがって、コンパイルされたライブラリを使用してドキュメントを簡単に配布できます。しかし、トラブルがヘッダファイルを解析し、機能を使用中のドキュメントを与える...しかし、おそらくそれは.Hに機能コメントにFRMの.cをコピーするいくつかのデプロイスクリプトを解決できることができIDEになります...
ビタミンBernatik

5

コメントはドキュメントではありません。関数のドキュメントは通常、2Kのテキストで、場合によっては図付きです。たとえば、Windows SDKの関数のドキュメントを参照してください。docへのコメントでそのようなことが許可されている場合でも、コメントを含むコードは読み取り不可になります。ドキュメントを作成する場合は、ワードプロセッサを使用します。


更新、最近では(Qtクリエーターのようなものを使用して)doxygen(またはクローン)の方法を文書化する方が簡単です。たとえば、qtcでは、コメントの数回前に/キーを押すだけです。仕事はあなたのために行われます。このようなことから、コードを文書化するためだけにワードプロセッサにジャンプしたいとは思わないでしょう。私はこれを2005年に許可していましたが、今は決してそうしませんでした。HTMLエディタを使用することさえ、今ではかなり古風なようです。
osirisgothra

@osirisgothra Doxygen-「ドキュメンテーション」は簡単に実行でき、迅速に記述された多くのLOCを確実に生成しますが、生成された「ドキュメンテーション」の価値は、ほとんどの場合、議論の余地があります。Doxygenのコメントは、優れたドキュメント(ほとんどすべての重要な詳細がひどく欠落している)でも、優れたコメントでもありません(署名からすでに明らかなことを繰り返す傾向があります)。nbtは、実際のドキュメントはコードと混同しないことが最善であると言っているのは正しいと思います。コードの可読性を損なうからです。とにかく同期が取れなくなりますが、特効薬はありません。
cmaster

4

ソースコードの利害関係者(たとえば、小さなライブラリ)が「ユーザー」(実装に関与せずにライブラリの機能を使用する開発者仲間)と「開発者」(ライブラリを実装する開発者)で構成される場合、その後、ヘッダーに「ユーザー情報」を、ソースに「実装メモ」を入れます。

ヘッダーファイルを絶対に必要以上に変更しないという要望に関しては、ライブラリが「変更の狂った流れ」にない場合、「インターフェイス」と「機能性」はあまり変わらず、ヘッダーのコメントが頻繁に変更される場合。一方、ソースコードのコメントは、ソースコードと同期( "新鮮")する必要があります。


0

doxygenを使用する全体のポイントは、ドキュメントを生成し、どこか他の場所からアクセスできるようにすることです。現在、ヘッダー内のすべてのドキュメントは単なるゴミであり、必要な関数宣言とそのオーバーロードをすばやく見つけるのが難しくなっています。そこに行くべきライナーコメントは最大ですが、それでも悪い習慣です。ソースのドキュメントを変更した場合、そのソースを再コンパイルして再リンクします。ただし、ドキュメントをヘッダーに配置する場合、実際には少しでも変更したくないので、プロジェクトの再構築のかなりの部分をトリガーすることになります。


1
これは、以前の7つの回答で作成され説明されたポイントに対して実質的な何かを提供していないようです
-gnat

1
以前の7つの回答の@gnatは、ヘッダーに対するコードを支持するのは1つだけです。そして、それは全く異なる議論を与えています。
スラバ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.