Apakah lebih baik mendokumentasikan fungsi dalam file header atau file sumber?

86

Dalam bahasa yang membedakan antara file "sumber" dan "header" (terutama C dan C ++), apakah lebih baik mendokumentasikan fungsi dalam file header:

(dicuri dari 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);

atau dalam file sumber?

(dicuri dari 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)
{
...

Perhatikan bahwa beberapa hal didefinisikan hanya dalam tajuk, seperti struct, makro, dan static inlinefungsi. Saya hanya berbicara tentang hal-hal yang dideklarasikan dalam file header dan didefinisikan dalam file sumber.

Inilah beberapa argumen yang bisa saya pikirkan. Saya cenderung mendokumentasikan file sumber, jadi argumen "Pro-header" saya mungkin agak lemah.

Pro-header:

  • Pengguna tidak memerlukan kode sumber untuk melihat dokumentasi.
    • Sumbernya mungkin tidak nyaman, atau bahkan tidak mungkin, untuk diperoleh.
    • Ini membuat antarmuka dan implementasi semakin terpisah.

Pro-sumber:

  • Itu membuat header jauh lebih pendek, memberikan pembaca pandangan mata-burung dari modul secara keseluruhan.
  • Ini memasangkan dokumentasi dari suatu fungsi dengan implementasinya, membuatnya lebih mudah untuk melihat bahwa suatu fungsi melakukan apa yang dikatakannya.

Saat menjawab, harap waspada terhadap argumen berdasarkan alat apa dan "IDE modern" dapat lakukan. Contoh:

  • Pro-header: Pelipatan kode dapat membantu membuat tajuk komentar lebih mudah dinavigasi dengan menyembunyikan komentar.
  • Pro-sumber: cscope 's Find this global definitionfitur membawa Anda ke file sumber (di mana definisi ini) daripada file header (di mana deklarasi ini).

Saya tidak mengatakan jangan membuat argumen seperti itu, tetapi ingatlah bahwa tidak semua orang merasa nyaman dengan alat yang Anda gunakan.

Joey Adams
sumber
Pertanyaan yang sama dapat diterapkan pada Pascal / Delphi di mana kita tidak memiliki file sumber dan header, tetapi bagian antarmuka dan implementasi.
Jan Doggen

Jawaban:

96

Pandangan ku...

  • Dokumentasikan cara menggunakan fungsi dalam file header, atau lebih dekat dengan deklarasi.

  • Dokumentasikan bagaimana fungsi bekerja (jika tidak jelas dari kode) dalam file sumber, atau lebih tepatnya, dekat dengan definisi.

Untuk hal burung-mata di header, Anda tidak perlu dokumentasi yang dekat - Anda dapat mendokumentasikan kelompok deklarasi sekaligus.

Secara umum, penelepon harus tertarik pada kesalahan dan pengecualian (jika hanya mereka dapat diterjemahkan karena mereka menyebar melalui lapisan abstraksi) sehingga ini harus didokumentasikan dekat dengan deklarasi yang relevan.

Steve314
sumber
13
+1 - yaitu mendokumentasikan antarmuka di header. Rincian Gory tentang bagaimana dan mengapa di sumbernya.
cepat,
2
Untuk tajuk perpustakaan di mana tidak ada sumber yang tersedia mungkin menambahkan kondisi pra dan posting, dll ... untuk membantu dengan pengujian. Ditambah menambahkan O (n) kinerja jika itu masuk akal, sehingga pengguna perpustakaan dapat memilih dengan bijak.
Patrick Hughes
Secara alami, terkadang deklarasi dan definisi adalah satu dan sama.
Deduplicator
@Deduplicator - ketika aturan yang sama masih mengarah ke hal yang benar bahkan dalam kasus khusus, mengapa mengulangi aturan tersebut untuk setiap kasus khusus? Tentunya seorang deduplicator seharusnya tidak menginginkan itu?
Steve314
1
@Dupuplikator - tentu saja itu adalah pemikiran yang terlalu besar untuk tidak mengikuti saran Anda, tapi saya tetap menggunakannya.
Steve314
34

Jika Anda akan menggunakan alat seperti Doxygen (perhatikan dalam contoh pertama, itu benar-benar terlihat seperti komentar Doxygen karena dimulai dengan /**) maka tidak terlalu masalah - Doxygen akan melihat melalui header dan file sumber Anda dan menemukan semua komentar untuk menghasilkan dokumentasi.

Namun, saya akan lebih cenderung untuk meletakkan komentar dokumentasi di header, di mana deklarasi tersebut berada. Klien Anda akan berurusan dengan header untuk berinteraksi dengan perangkat lunak Anda, header adalah apa yang akan mereka sertakan dalam file sumber mereka sendiri dan di situlah mereka akan mencari terlebih dahulu untuk melihat seperti apa API Anda.

Jika Anda melihat sebagian besar pustaka Linux misalnya, sistem manajemen paket Linux Anda sering memiliki paket yang hanya berisi binari perpustakaan (untuk pengguna "normal" yang memiliki program yang memerlukan pustaka) dan Anda memiliki paket "dev" yang berisi tajuk untuk perpustakaan. Kode sumber biasanya tidak diberikan secara langsung dalam satu paket. Akan sangat merepotkan jika Anda harus mendapatkan kode sumber perpustakaan di suatu tempat untuk mendapatkan dokumentasi API.

Jesper
sumber
2
+1 - dengan ketentuan bahwa meskipun Anda menggunakan Doxygen, itu tidak berarti Anda tidak akan pernah membaca langsung dari sumbernya. Anotasi Doxygen bahkan kadang berguna sebagai pola standar untuk dipahami, dan ini berguna jika anotasi yang Anda temukan dekat dengan kode yang dijelaskannya.
Steve314
1
@ Steve314 tentu saja saya tidak mengatakan bahwa Anda tidak akan pernah ingin melihat kode sumber dari beberapa perpustakaan - tetapi itu bukan tempat pertama yang akan Anda cari seperti apa API itu dan bagaimana menggunakannya.
Jesper
Saya juga akan menganjurkan untuk menjaga segala sesuatu yang terkait dengan API di header (atau setidaknya di header atau sumber), karena itu akan menghindari potensi inkoherensi ketika memperbarui dokumentasi di satu tempat dan bukan di tempat lain.
jopasserat
12

Kami memecahkan masalah ini (sekitar 25 tahun yang lalu) dengan membuat banyak # definisi (mis. Publik, pribadi, dll., Yang teratasi menjadi <tidak ada>) yang dapat digunakan dalam file sumber dan dipindai oleh skrip awk (horor !) untuk menghasilkan file .h secara otomatis. Ini berarti bahwa semua komentar tinggal di sumber dan disalin (bila perlu) ke dalam file .h yang dihasilkan. Saya tahu itu Sekolah Tua yang cantik, tetapi sangat menyederhanakan dokumentasi inline semacam ini.

Peter Rowell
sumber
1
hmm saya tahu gaya hal ini bisa berguna, tetapi dari sudut pandang saya, saya selalu menemukan dokumentasi semacam itu benar-benar menjengkelkan ...
osirisgothra
1
Mengutip Donald Rumsfeld (seorang pria saya tidak suka), "Kamu program dengan alat yang Anda miliki, bukan dengan alat yang Anda ingin Anda miliki." Setiap bahasa yang saya gunakan dalam 40+ tahun terakhir memiliki setidaknya satu kutil utama (jika tidak lebih). Solusi kami a) bekerja, b) menggunakan alat yang ada pada saat itu, c) mari kita habiskan waktu kita mengeluarkan kode penghasil pendapatan.
Peter Rowell
Meskipun saya mungkin tidak akan memilih ini, ini merupakan cara yang menarik untuk menangani komentar di header. Apakah tajuk yang dihasilkan dalam kontrol versi? atau apakah ini beberapa proses rilis untuk membuat sumber yang dapat didistribusikan? (tapi tidak digunakan oleh pengembang)
ideasman42
Oh, saya telah melihat pola yang sama baru-baru ini dalam sebuah proyek dimulai pada ≥ 2000 dan mereka sangat bangga dengan penemuan pintar mereka ...
5gon12eder
3
Dalam kasus kami, kami tidak menyimpan file yang dihasilkan di bawah kontrol versi karena mudah dan langsung (kembali) berasal dari file yang dilacak.
Peter Rowell
9

Dengan asumsi ini adalah kode dalam proyek yang lebih besar (di mana pengembang akan sering berpindah antara sumber dan tajuk) , dan menyediakan ini bukan perpustakaan / perangkat menengah, di mana orang lain mungkin tidak memiliki akses ke sumber, saya telah menemukan ini berfungsi terbaik...

  • Header:
    Terse 1-2 komentar baris, hanya jika mereka diperlukan.
    Terkadang komentar di atas sekelompok fungsi terkait juga membantu.
  • Sumber:
    Dokumentasi pada API langsung di atas fungsi (teks biasa atau doxygen jika Anda suka) .
  • Menyimpan detail implementasi, hanya relevan dengan pengembang yang memodifikasi kode di badan fungsi.

Alasan utama untuk ini adalah untuk menjaga komentar dekat dengan kode, saya perhatikan dokumen di header cenderung tidak sinkron dengan perubahan pada kode lebih sering (tentu saja tidak seharusnya, tetapi mereka lakukan dalam proyek kami di paling tidak) . Pengembang juga dapat menambahkan dokumentasi di bagian atas fungsi ketika mereka membuat beberapa perubahan, bahkan jika ada dokumen header ... di tempat lain. Menyebabkan double-up atau info berguna hanya berada di salah satu dokumen.

Tentu saja Anda dapat memilih konvensi dan memastikan semua pengembang mengikuti, saya baru saja menemukan konvensi di atas yang paling alami dan paling tidak menyulitkan untuk dipertahankan.


Terakhir dari semua, untuk proyek-proyek besar - ada kecenderungan untuk tidak membuat koreksi kecil di header ketika Anda tahu itu akan menyebabkan berpotensi 100 atau 1000 file untuk dikompilasi ulang ketika orang lain memperbarui kontrol versi - memperlambat kesalahan membagi dua juga.

gagasanman42
sumber
5

Menurut saya (agak terbatas dan bias), saya berpikir cara kode pro-sumber. Ketika saya melakukan sedikit demi sedikit dalam C ++, saya biasanya mengedit file header sekali dan kemudian saya tidak pernah benar-benar kembali untuk melihatnya.

Ketika saya menempatkan dokumentasi di file sumber, saya selalu melihatnya ketika saya mengedit atau membaca kode. Saya kira itu adalah kebiasaan.

Tapi itu hanya aku ...

MattyD
sumber
1
Tidak berfungsi dengan baik jika semua yang Anda miliki adalah pustaka yang dikompilasi dan file header. Dalam hal ini, lebih banyak info dalam tajuk adalah hal yang baik karena ini adalah satu-satunya dokumentasi antarmuka yang Anda miliki.
cepat,
Anda dapat membuat dokumentasi dengan doxygen - ini juga mengambilnya dari file .c. Dengan demikian Anda dapat mendistribusikan dokumentasi dengan mudah dengan perpustakaan yang dikompilasi. Tetapi masalahnya adalah dengan IDE yang dapat mem-parsing file header dan memberi Anda dokumentasi saat menggunakan fungsi ... Tapi mungkin bisa menyelesaikan beberapa skrip deploy yang akan menyalin komentar fungsi frm .c ke .h ...
Vit Bernatik
5

Komentar bukan dokumentasi. Dokumentasi untuk fungsi biasanya 2K teks, mungkin dengan diagram - lihat misalnya dokumentasi untuk fungsi di Windows SDK. Bahkan jika komentar-ke-dok Anda memungkinkan hal seperti itu, Anda akan membuat kode yang berisi komentar tidak dapat dibaca. Jika Anda ingin menghasilkan dokumentasi, gunakan pengolah kata.

Neil Butterworth
sumber
memperbarui, jauh lebih mudah untuk mendokumentasikan hari ini (dengan hal-hal seperti pembuat Qt di luar sana) untuk hanya mendokumentasikan cara doxygen (atau klon), misalnya, dalam qtc Anda cukup menekan tombol / beberapa kali sebelum komentar dan setengah pekerjaan dilakukan untukmu. Karena hal-hal seperti ini, saya ragu orang akan ingin beralih ke pengolah kata hanya untuk mendokumentasikan kode mereka. Saya biasa melakukan ini, memang, pada tahun 2005, tetapi saya tidak akan pernah melakukannya sekarang. Bahkan menggunakan editor html tampaknya cukup kuno sekarang.
osirisgothra
@osirisgothra Doxygen- "dokumentasi" mungkin mudah dilakukan, dan tentu saja menghasilkan banyak LOC yang ditulis dengan cepat, tetapi nilai "dokumentasi" yang dihasilkan masih dapat diperdebatkan dalam sebagian besar kasus. Komentar Doxygen bukanlah dokumentasi yang baik (hampir semua detail penting hilang secara genetis), juga bukan komentar yang baik (mereka cenderung mengulangi apa yang sudah jelas dari tanda tangan). Saya pikir nbt benar dalam mengatakan bahwa dokumentasi nyata lebih baik tidak dicampur dengan kode karena itu merusak keterbacaan kode. Itu akan keluar dari sinkronisasi, tidak ada peluru perak untuk itu.
cmaster
4

Jika pemangku kepentingan kode sumber Anda (misalnya, perpustakaan kecil) terdiri dari "pengguna" (sesama pengembang yang akan menggunakan fungsionalitas perpustakaan Anda tanpa terlibat dalam implementasinya) dan "pengembang" (Anda dan pengembang lain yang akan mengimplementasikan perpustakaan) , lalu letakkan "informasi pengguna" di header dan "catatan implementasi" di sumber.

Berkenaan dengan keinginan untuk tidak mengubah file header lebih dari yang benar-benar diperlukan - saya kira jika perpustakaan Anda tidak "dalam perubahan perubahan gila", bahwa "antarmuka" dan "fungsionalitas" tidak akan banyak berubah, dan tidak ada haruskah komentar tajuk berubah terlalu sering. Di sisi lain, komentar kode sumber harus tetap disinkronkan ("segar") dengan kode sumber.

rwong
sumber
0

Inti dari penggunaan doxygen adalah Anda menghasilkan dokumentasi dan membuatnya dapat diakses di tempat lain. Sekarang semua dokumentasi di header hanyalah sampah yang membuatnya lebih sulit untuk dengan cepat menemukan pernyataan fungsi yang diperlukan, dan mungkin kelebihannya. Satu komentar liner adalah maksimum yang seharusnya ada di sana, tetapi bahkan itu adalah praktik yang buruk. Penyebab jika Anda mengubah dokumentasi di sumber, Anda mengkompilasi ulang sumber itu dan menghubungkan kembali. Tetapi jika Anda meletakkan dokumen di header Anda benar-benar tidak ingin mengubah sedikit pun di sana, karena itu akan memicu bagian penting dari pembangunan kembali proyek.

Slava
sumber
1
ini tampaknya tidak menawarkan sesuatu yang substansial atas poin yang dibuat dan dijelaskan dalam 7 jawaban sebelumnya
nyamuk
1
@gnat dari 7 jawaban sebelumnya hanya satu yang mendukung kode terhadap tajuk. Dan yang satu itu memberikan argumentasi yang sama sekali berbeda.
Slava