Чи краще документувати функції у файлі заголовка чи у вихідному файлі?


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функції. Я говорю лише про речі, які задекларовані у файлі заголовка та визначені у вихідному файлі.

Ось кілька аргументів, які я можу придумати. Я схиляюся до документування у вихідному файлі, тому мої аргументи "заголовок" можуть бути дещо слабкими.

Проголовок:

  • Користувачеві не потрібен вихідний код для перегляду документації.
    • Джерело може бути незручним або навіть неможливим придбати.
    • Це зберігає інтерфейс та реалізацію далі.

Про-джерело:

  • Це робить заголовок набагато коротшим, надаючи читачеві огляд модуля в цілому.
  • Він поєднує документацію функції з її реалізацією, полегшуючи побачити, що функція робить те, що, як вона каже, робить.

Відповідаючи, будьте уважні до аргументів, виходячи з того, які інструменти та "сучасні ІДЕ" можуть зробити. Приклади:

  • Прозаголовок: складання коду може допомогти зробити коментовані заголовки більш зручними, ховаючи коментарі.
  • Pro-джерело: Cscope «s Find this global definitionфункція приймає вас до вихідного файлу (де визначення є) , а не файл заголовка (де декларація є).

Я не кажу, що не варто наводити таких аргументів, але майте на увазі, що не всім так зручно користуватися інструментами, якими ви користуєтесь.


Це ж питання може стосуватися і Pascal / Delphi, де у нас немає вихідних та заголовок файлів, але розділів інтерфейсу та реалізації.
Ян Догген

1
Дивіться також stackoverflow.com/questions/355619 / ...
cp.engr

Відповіді:


96

Мій погляд ...

  • Документуйте, як використовувати функцію у файлі заголовка, або точніше близько до декларації.

  • Документуйте, як функціонує функція (якщо це не очевидно з коду) у вихідному файлі, а точніше - близькому до визначення.

Що стосується пташиного погляду в заголовку, вам не обов’язково потрібна документація, яка закривається - ви можете документувати групи декларацій відразу.

Взагалі кажучи, абонента повинні бути зацікавлені в помилках і винятках (якщо тільки так вони можуть бути перекладені, коли вони пропонують через шари абстракції), тому вони повинні бути задокументовані близько до відповідних декларацій.


13
+1 - тобто документуйте інтерфейс у заголовку. Деталі про Горі про те, як і чому в джерелі.
quick_now

2
Для заголовків бібліотеки, де немає джерела, можливо, додайте умови до і після, і т. Д. ..., щоб допомогти з тестуванням. Плюс додайте продуктивність O (n), якщо це має сенс, тому користувачі бібліотеки можуть вибирати розумно.
Патрік Х'юз

Природно, що іноді декларація та визначення - це одне й те саме.
Дедуплікатор

@Deduplicator - коли ті ж правила все ж призводять до правильної речі навіть у спеціальному випадку, навіщо повторювати ці правила для кожного окремого випадку? Невже дедупликатор не повинен цього бажати?
Стів314

1
@Deduplicator - це, звичайно, масово обґрунтоване обгрунтування того, щоб не дотримуватися ваших порад, але я дотримуюся цього.
Steve314

34

Якщо ви збираєтесь використовувати такий інструмент, як Doxygen (зверніть увагу на перший приклад, який насправді схожий на коментар Doxygen, тому що він починається з /**), це насправді не має значення - Doxygen перегляне ваші заголовки та вихідні файли та знайде всі коментарі для створення документації.

Однак я б більше схильний помістити коментарі до документації в заголовках, де є декларації. Ваші клієнти матимуть справу із заголовками для взаємодії з вашим програмним забезпеченням, заголовки - це те, що вони будуть включати у власні вихідні файли, і саме там вони спочатку шукатимуть, щоб побачити, як виглядає ваш API.

Якщо ви, наприклад, переглядаєте більшість бібліотек Linux, у вашій системі управління пакетами Linux часто є пакет, який містить лише бінарні файли бібліотеки (для "звичайних" користувачів, у яких програми, які потребують бібліотеку), і у вас є пакет "dev", який містить заголовки бібліотеки. Вихідний код зазвичай не постачається безпосередньо в пакеті. Було б дуже громіздко, якби вам довелося десь отримати вихідний код бібліотеки, щоб отримати документацію API.


2
+1 - за умови, що навіть якщо ви використовуєте Doxygen, це не означає, що ви ніколи не збираєтесь читати безпосередньо з джерела. Анотації про доксиген навіть іноді корисні як стандартні зразки, для яких потрібно схвалювати, і це зручно, якщо знайдені вами анотації близькі до коду, який він описує.
Steve314

1
@ Steve314 звичайно. Я не сказав, що ви ніколи не хочете подивитися вихідний код якоїсь бібліотеки - але це не буде першим місцем, де ви б шукали, як виглядає API і як ним користуватися.
Jesper

Я б також рекомендував зберігати все, що стосується API, у заголовку (або принаймні у заголовку чи джерелі), оскільки це дозволить уникнути потенційної невідповідності при оновленні документації в одному місці, а не в іншому.
jopasserat

12

Ми вирішили цю проблему (близько 25 років тому), створивши купу #defines (наприклад, загальнодоступних, приватних тощо), які вирішили до <нічого>), які можуть бути використані у вихідному файлі та скановані за допомогою awk-сценарію (жахи !) для автоматичного генерування .h файлів. Це означає, що всі коментарі знаходились у джерелі та були скопійовані (коли це доречно) у створений файл .h. Я знаю, що це досить стара школа, але вона значно спростила подібну документацію.


1
Хм, я знаю, що цей стиль речі може бути корисним, але, з моєї точки зору, я завжди вважав, що така документація буде прямо дратує ...
osirisgothra

1
Перефразовуючи Дональда Рамсфельда (чоловіка, який мені не сподобався), "Ви програмуєте з інструментами, які є у вас, а не з інструментами, які ви хотіли б мати". Кожна мова, з якою я працював протягом останніх 40+ років, мала хоча б одну головну бородавку (якщо не більше). Наше рішення: а) працювали; б) використовувались інструменти, які існували в той час; в) давайте витрачати свій час на отримання коду, що приносить прибуток.
Пітер Роуелл

Хоча я, мабуть, не став би цього робити, це цікавий спосіб обробляти коментарі в заголовках. Чи будуть створені заголовки в контролі версій? чи це якийсь процес випуску для перерозподілу джерела? (але не використовується розробниками)
Ideman42

О, я спостерігав таку ж схему нещодавно в проекті, розпочатому в 2000 році, і вони так пишалися своїм розумним винаходом ...
5gon12eder

3
У нашому випадку ми не тримали жоден із створених файлів під контролем версій, оскільки вони легко та безпосередньо (повторно) отримувались від відстежуваних файлів.
Пітер Роуелл

9

Якщо припустити, що це код у рамках більшого проекту (де розробники будуть часто рухатися між джерелами та заголовками) , і якщо це не бібліотека / середній посуд, де інші, можливо, не мають доступу до джерела, я знайшов це працює найкращий ...

  • Заголовки:
    Оберіть 1-2 рядкові коментарі, лише якщо вони потрібні.
    Іноді коментарі над групою пов’язаних функцій також корисні.
  • Джерело:
    Документація на API безпосередньо над функцією (звичайний текст або доксиген, якщо вам зручніше) .
  • Зберігайте деталі реалізації, що стосуються лише розробника, який модифікує код в тілі функції.

Основна причина цього полягає в тому, щоб коментарі були близькими до коду, я помічав, що документи в заголовках частіше виходять із синхронізації зі змінами коду (звичайно, не повинні, але це було в нашому проекті на мінімум) . Також розробники можуть додавати документацію у верхній частині функцій, коли вони вносять деякі зміни, навіть якщо є документи заголовка ... десь ще. Викликання подвійних зображень або корисної інформації лише в одному з рядків doc.

Звичайно, ви можете підібрати конвенцію і забезпечити, щоб усі дияволи дотримувались, я щойно знайшов цю конвенцію вище за найбільш природну форму і завдає найменших проблем у підтримці.


Нарешті, для великих проектів - це схильність не вносити невеликі виправлення в заголовок, коли ви знаєте, що це призведе до того, що потенційно 100 або 1000 файлів будуть перекомпільовані, коли інші оновлюють контроль версій - також сповільнюючи помилки розбиття.


5

На мій (досить обмежений і упереджений) погляд, я про-вихідний код мислення. Коли я роблю шматочки та фрагменти в C ++, я зазвичай редагую файл заголовка один раз, і тоді я ніколи не повертаюся до нього.

Коли я розміщую документацію у вихідному файлі, я завжди бачу її під час редагування чи читання кодів. Я здогадуюсь, це справа звички.

Але це тільки я ...


1
Не дуже добре, якщо у вас є лише складена бібліотека та файл заголовка. У цьому випадку більше інформації в заголовку - це гарна річ, тому що це єдина у вас документація на інтерфейс.
quick_now

Ви можете створити документацію за допомогою doxygen - він також бере її з файлів .c. Таким чином, ви могли легко поширювати документацію зі складеними бібліотеками. Але проблема буде з IDE, який може проаналізувати файли заголовків і надати документацію під час використання функції ... Але, можливо, це може вирішити якийсь сценарій розгортання, який би скопіював коментарі до функції frm .c в .h ...
Віт Бернатик,

5

Коментарі - це не документація. Документація для функції зазвичай може бути 2K тексту, можливо, з діаграмами - див., Наприклад, документацію для функцій в SDK Windows. Навіть якщо ваш коментар до документа дозволяє таке, ви зробите код, що містить коментар, нечитаним. Якщо ви хочете виготовити документацію, використовуйте текстовий процесор.


оновлення, набагато простіше документувати в ці дні (з такими речами, як творець Qt там), щоб просто документувати доксигенний (або клонний) спосіб, наприклад, у qtc ви просто натискаєте клавішу / клавішу кілька разів перед коментарем і наполовину робота робиться за вас. Через такі речі, я сумніваюся, люди захочуть перейти до текстового процесора просто для документування свого коду. Раніше я це робив, дано, ще в 2005 році, але я б ніколи цього не робив. Навіть використання редактора html зараз здається досить архаїчним.
osirisgothra

@osirisgothra Doxygen- "документація" може бути легко зробити, і, безумовно, створює багато швидко написаних LOC, але цінність виготовленої "документації" залишається спірною у переважній більшості випадків. Коментарі доксигену не є ні гарною документацією (майже всі найважливіші деталі загалом відсутні), ні хороші коментарі (вони, як правило, повторюють те, що вже очевидно з підпису). Я думаю, що nbt правильно сказати, що справжню документацію найкраще не змішувати з кодом, оскільки це шкодить читабельності коду. Це все одно вийде із синхронізації, для цього немає жодної срібної кулі.
cmaster

4

Якщо зацікавлені сторони вашого вихідного коду (скажімо, невелика бібліотека) складаються з "користувачів" (колег-розробників, які використовуватимуть функціональність вашої бібліотеки, не беручи участь у її впровадженні) та "розробників" (ви та інші розробники, які реалізуватимуть бібліотеку) , потім помістіть "інформацію про користувачів" у заголовок та "примітку про реалізацію" у джерелі.

Що стосується бажання не змінювати файли заголовків більше, ніж це абсолютно необхідно - я вважаю, якщо ваша бібліотека не "в шаленому потоці змін", "інтерфейс" і "функціональність" не сильно зміниться, і ні якщо коментарі до заголовка змінюються занадто часто. З іншого боку, коментарі до вихідного коду повинні бути синхронізованими ("свіжими") з вихідним кодом.


0

Вся суть використання доксигену полягає в тому, що ви генеруєте документацію та робите її доступною десь в іншому місці. Тепер вся ця документація у заголовках - це лише сміття, що ускладнює швидке виявлення необхідної декларації функціоналу, а може бути і її перевантаження. Один коментар лайнера максимум, що має бути там, але навіть це погана практика. Причиною, якщо ви змінюєте документацію в джерелі, ви перекомпілюєте це джерело і перейменовете посилання. Але якщо ви помістите документи в заголовок, ви насправді не хочете змінити ні найменшої речі, тому це призведе до значної частини перебудови проекту.


1
це, здається, не пропонує нічого суттєвого щодо питань, викладених та пояснених у попередніх 7 відповідях
gnat

1
@gnat з попередніх 7 відповідей, лише одна підтримує код проти заголовків. І це наводить зовсім іншу аргументацію.
Слава
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.