web-dev-qa-db-ja.com

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

「ソース」ファイルと「ヘッダー」ファイル(主に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機能により、ヘッダーファイル(ではなくdefinitionがある)ソースファイル(ここで宣言です)。

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

94
Joey Adams

私の見解...

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

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

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

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

101
Steve314

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

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

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

35
Jesper

私たちはこの問題を(約25年前に)ソースファイルで使用でき、awkスクリプト(恐怖!).hファイルを自動生成します。これは、すべてのコメントがソースに存在し、(適切な場合)生成された.hファイルにコピーされたことを意味します。私はそれがかなり古い学校であることを知っていますが、それはこの種のインライン文書を大幅に簡略化しました。

12
Peter Rowell

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

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

これの主な理由は、コメントをコードに近づけるためです。ヘッダーのドキュメントは、コードへの変更と頻繁に同期しなくなる傾向があることに気付きました(もちろん、それらはすべきではありません) t、しかし、少なくとも私たちのプロジェクトではそうでした)。また、開発者は、ヘッダーにドキュメントがある場合でも、変更を加えたときに関数の一番上にドキュメントを追加し、ダブルアップまたは有用な情報がdoc-stringの1つにのみ含まれるようにすることができます。

もちろん、規則を選択してすべての開発者が従うようにすることもできます。私は、規則が最も上natural-fitであることを確認しただけで、メンテナンスの手間を最小限に抑えます。


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

9
ideasman42

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

6

私の(かなり限定的で偏った)意見では、私はプロソースコードの考え方です。 C++で細かい部分を行う場合、通常はヘッダーファイルを1度編集しますが、実際に戻ってそれを確認することはありません。

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

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

5
MattyD

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

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

4
rwong

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

0
Slava