헤더 파일이나 소스 파일에 함수를 문서화하는 것이 더 낫습니까?


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-header"인수가 다소 약할 수 있습니다.

프로 헤더 :

  • 사용자는 설명서를보기 위해 소스 코드가 필요하지 않습니다.
    • 소스를 얻는 것이 불편하거나 불가능할 수도 있습니다.
    • 이것은 인터페이스와 구현을 더 멀리 유지합니다.

프로 소스 :

  • 헤더를 훨씬 짧게 만들어 독자에게 모듈 전체를 조감 할 수 있습니다.
  • 함수의 문서를 구현과 결합하여 함수가 말하는 기능을 쉽게 수행 할 수 있습니다.

대답 할 때 도구와 "현대 IDE"가 할 수있는 일에 근거한 논쟁에주의하십시오. 예 :

  • 프로 헤더 : 코드를 접 으면 주석을 숨겨 주석이 달린 헤더를보다 쉽게 ​​탐색 할 수 있습니다.
  • Pro-source : cscopeFind this global definition기능은 헤더 파일 ( 선언 이 있는)이 아니라 소스 파일 ( 정의 가있는)로 이동합니다 .

나는 그런 주장을하지 않는다고 말하는 것이 아니라, 모든 사람이 당신이 사용하는 도구에 익숙하지 않다는 것을 명심해야한다.


Pascal / Delphi에도 소스와 헤더 파일이 없지만 인터페이스 및 구현 섹션이있는 동일한 질문이 적용될 수 있습니다.
Jan Doggen

답변:


96

내 견해 ...

  • 헤더 파일에서 함수를 사용하는 방법을 문서화하거나 선언에 더 가깝게 문서화하십시오.

  • 소스 파일에서 함수가 어떻게 작동하는지 (코드에서 명확하지 않은 경우) 정의에 더 가깝게 문서화하십시오.

헤더의 조감도에 대해서는 반드시 가까운 문서가 필요하지 않습니다. 선언 그룹을 한 번에 문서화 할 수 있습니다.

광범위하게 말하면, 호출자는 오류와 예외에 관심을 가져야하며 (추상 계층을 통해 전파 될 때만 변환 될 수있는 경우에만) 관련 선언에 가깝게 문서화되어야합니다.


13
+1-즉, 인터페이스를 인터페이스에 문서화하십시오. Gory는 소스에서 방법과 이유에 대해 자세히 설명합니다.
quick_now

2
소스가없는 라이브러리 헤더의 경우 사전 및 사후 조건 등을 추가하여 테스트에 도움을 줄 수 있습니다. 또한 의미가있는 경우 O (n) 성능을 추가하여 라이브러리 사용자가 현명하게 선택할 수 있습니다.
Patrick Hughes

당연히 선언과 정의는 하나이며 동일합니다.
중복 제거기

@ 중복 제거기-동일한 규칙이 여전히 특별한 경우에도 옳은 것으로 이어질 때 왜 모든 특별한 경우에 대해 그 규칙을 반영합니까? 반드시 중복 제거기가 그것을 원하지 않아야합니까?
Steve314

1
@Deduplicator-물론 그것은 당신의 조언을 따르지 않은 것에 대해 엄청나게 과장된 이론적 근거이지만, 나는 그것을 고수하고 있습니다.
Steve314

34

Doxygen 과 같은 도구를 사용하려는 경우 (첫 번째 예제에서는으로 시작하기 때문에 실제로 Doxygen 주석처럼 보입니다 /**) 실제로 중요하지 않습니다 .Doxygen은 헤더와 소스 파일을 살펴보고 찾습니다. 모든 주석은 문서를 생성합니다.

그러나 선언이있는 헤더에 문서 주석을 넣는 경향이 더 큽니다. 클라이언트는 소프트웨어와 인터페이스하기 위해 헤더를 처리 할 것이고, 헤더는 자신의 소스 파일에 포함 할 것이므로 API가 어떻게 보이는지 먼저 살펴볼 것입니다.

예를 들어 대부분의 Linux 라이브러리를 살펴보면 Linux 패키지 관리 시스템에는 라이브러리의 바이너리 만 포함 된 패키지 (라이브러리가 필요한 프로그램이있는 "일반적인"사용자) 만 포함하는 패키지가 있고 "dev"패키지가 있습니다. 라이브러리의 헤더를 포함합니다. 소스 코드는 일반적으로 패키지에 직접 제공되지 않습니다. API 문서를 얻기 위해 어딘가에 라이브러리의 소스 코드를 가져와야하는 경우 정말 번거로울 것입니다.


2
+1-Doxygen을 사용하더라도 소스에서 직접 읽지 않는다는 의미는 아닙니다. Doxygen 주석은 grep하기위한 표준 패턴으로 유용 할 수 있으며 찾은 주석이 설명하는 코드와 가까운 경우에 유용합니다.
Steve314

1
@ Steve314 물론 나는 당신이 어떤 라이브러리의 소스 코드를보고 싶지 않다고 말하지는 않았지만 API가 어떻게 보이고 어떻게 사용되는지를 찾는 것은 처음이 아닙니다.
Jesper

또한 API와 관련된 모든 것을 헤더 (또는 적어도 헤더 또는 소스)에 보관하는 것이 좋습니다. 문서를 한 곳에서 다른 곳이 아닌 업데이트 할 때 잠재적으로 불일치가 발생하지 않기 때문입니다.
jopasserat

12

소스 파일에서 사용할 수 있고 awk 스크립트 (공포)로 스캔 할 수있는 #defines (예 : <nothing>으로 변환 된 공개, 개인 등)를 만들어이 문제를 해결했습니다 (약 25 년 전). !) .h 파일을 자동 생성합니다. 이는 모든 주석이 소스에 존재하고 생성 된 .h 파일에 (적절한 경우) 복사되었음을 의미합니다. 나는 그것이 올드 스쿨이라는 것을 알고 있지만, 이런 종류의 인라인 문서를 크게 단순화했습니다.


1
흠 나는 이런 스타일이 유용 할 수 있다는 것을 알고 있지만, 내 입장에서 나는 항상 그런 종류의 문서가 완전히 성가신다는 것을 알았다 ...
osirisgothra

1
Donald Rumsfeld (내 마음에 들지 않은 사람)의 말을 인용하자면 , "당신은 당신이 원했던 도구가 아니라 당신이 가진 도구로 프로그램합니다." 지난 40 년 동안 함께 일한 모든 언어에는 적어도 하나의 주요 사마귀가있었습니다 (더 이상은 아닙니다). 우리의 솔루션 a)는 효과가 있었으며 b) 당시 존재했던 도구를 사용했습니다. c) 우리는 시간을 들여 수익을 창출하는 코드를 만들어 냈습니다.
피터 로웰

아마 이것을 선택하지 않더라도 헤더에서 주석을 처리하는 흥미로운 방법입니다. 생성 된 헤더가 버전 제어에 있습니까? 또는 재배포 가능 소스를 만들기위한 일부 릴리스 프로세스입니까? (개발자는 사용하지 않음)
ideasman42

아, 프로젝트에서 최근에 같은 패턴을 보았다는 ≥ 2000 년에 시작하고 있었다 그래서 ... 그 영리한 발명의 자랑
5gon12eder

3
우리의 경우에는 생성 된 파일을 추적 된 파일에서 쉽고 직접적으로 파생 되었기 때문에 버전 제어를 받지 않았습니다 .
피터 로웰

9

이 큰 프로젝트에서 코드입니다 가정 (개발자는 종종 소스와 헤더 사이를 이동하는 것) ,이 제공하는 것이 아닌 다른 사람이 소스에 액세스 할 수 없습니다 도서관 / 미들웨어, 나는이 작품을 발견했습니다 베스트...

  • 머리글 :
    필요한 경우에만 1-2 줄 주석을 입력하십시오.
    때때로 관련 기능 그룹 위의 주석도 도움이됩니다.
  • 출처 :
    함수 바로 위에있는 API에 대한 문서 (원하는 경우 일반 텍스트 또는 독소) .
  • 함수 본문에서 코드를 수정하는 개발자와 만 관련하여 구현 세부 사항을 유지하십시오.

이것의 주된 이유는 주석을 코드에 가깝게 유지하는 것입니다. 헤더의 문서는 코드 변경과 더 자주 동기화되지 않는 경향이 있음을 알았습니다 (물론 그렇지 않아야하지만 프로젝트에서 최소한) . 또한 개발자는 헤더 문서가 있거나 다른 곳이 있더라도 약간의 변경을 할 때 함수 상단에 문서를 추가 할 수 있습니다. 더블 업 또는 유용한 정보가 문서 문자열 중 하나에 만 있도록합니다.

물론 컨벤션을 선택하고 모든 개발자가 준수하도록 할 수 있습니다. 컨벤션은 가장 자연스럽게 적합 하며 유지 관리에 문제가 거의 없습니다.


마지막으로, 대규모 프로젝트의 경우- 다른 사람들이 버전 제어를 업데이트 할 때 잠재적으로 100 또는 1000 파일의 파일이 다시 컴파일 될 것이라는 것을 알 때 헤더에서 작은 수정을 하지 않는 경향 이 있습니다-bisecting 오류도 느려집니다.


5

내 (제한적이고 편견이 아닌) 의견으로는, 나는 소스 코드 사고 방식입니다. C ++에서 비트와 조각을 할 때 일반적으로 헤더 파일을 한 번 편집 한 다음 절대 다시 돌아 가지 않습니다.

소스 파일에 문서를 배치하면 코드를 편집하거나 읽을 때 항상 문서가 표시됩니다. 그것은 습관적인 것 같아요.

하지만 그건 나 뿐이야


1
컴파일 된 라이브러리와 헤더 파일 만 있으면 제대로 작동하지 않습니다. 이 경우 헤더에있는 유일한 정보는 인터페이스 설명서가 있기 때문에 좋은 정보입니다.
quick_now

doxygen으로 문서를 생성 할 수 있습니다. .c 파일에서도 가져옵니다. 따라서 컴파일 된 라이브러리로 문서를 쉽게 배포 할 수 있습니다. 그러나 문제는 헤더 파일을 구문 분석하고 함수를 사용하는 동안 문서를 제공 할 수있는 IDE의 문제 일 것입니다. 그러나 아마도 함수 주석 frm .c를 .h로 복사하는 배포 스크립트를 해결할 수 있습니다.
Vit Bernatik

5

의견은 문서가 아닙니다. 함수에 대한 문서는 일반적으로 다이어그램과 함께 2K 텍스트 일 ​​수 있습니다 (예 : Windows SDK의 함수에 대한 문서 참조). 주석 투 독 (doc-to-doc)이 그러한 것을 허용하더라도 주석이 포함 된 코드를 읽을 수 없게 만듭니다. 문서를 작성하려면 워드 프로세서를 사용하십시오.


업데이트, 요즘 문서화하는 것이 훨씬 쉽습니다 (Qt creator와 같은 것들로) doxygen (또는 clone) 방식을 문서화하는 것입니다. 예를 들어 qtc에서는 주석 전에 / 키를 몇 번 누르십시오. 일은 당신을 위해 이루어집니다. 이와 같은 것들 때문에 사람들이 코드를 문서화하기 위해 워드 프로세서로 이동하기를 원할 것입니다. 예전에는 2005 년에이 작업을 수행했지만 지금은 그렇게하지 않습니다. html 편집기를 사용하는 것조차도 꽤 구식 적 인 것 같습니다.
osirisgothra

@osirisgothra Doxygen- "documentation"은 쉽게 수행 할 수 있고, 빠르게 작성된 LOC를 많이 생성하지만, 생성 된 "documentation"의 가치는 대부분의 경우 논쟁의 여지가 있습니다. Doxygen 의견은 좋은 문서가 아니며 (거의 모든 중요한 세부 사항이 일반적으로 누락되어 있음) 좋은 의견이 아닙니다 (서명에서 이미 분명한 내용을 반복하는 경향이 있음). 실제 문서는 코드 가독성에 해 롭기 때문에 코드와 혼합되지 않는 것이 가장 좋다고 생각합니다. 어쨌든 동기화되지 않을 것입니다.
cmaster

4

소스 코드의 이해 당사자 (예 : 소규모 라이브러리)가 "사용자"(구현에 관여하지 않고 라이브러리 기능을 사용하는 개발자)와 "개발자"(사용자 및 라이브러리를 구현할 다른 개발자)로 구성된 경우 그런 다음 "사용자 정보"를 헤더에, "구현 노트"를 소스에 넣습니다.

헤더 파일을 절대적으로 필요 이상으로 변경하지 않으려는 욕구와 관련하여-라이브러리가 "매우 많은 변화"에 있지 않은 경우 "인터페이스"와 "기능"이 크게 변경되지 않으며 헤더 주석이 너무 자주 변경되어야합니다. 반면, 소스 코드 주석은 소스 코드와 동기화 된 상태로 유지되어야합니다 ( "신선한").


0

doxygen 사용의 요점은 문서 를 생성 하고 다른 곳에서 액세스 할 수 있도록하는 것입니다. 이제 헤더의 모든 문서는 가비지이므로 필요한 함수 선언 및 과부하를 신속하게 발견하기가 더 어려워집니다. 하나의 라이너 의견이 최대가 될 수 있지만, 심지어 나쁜 습관입니다. 소스에서 문서를 변경하면 해당 소스를 다시 컴파일하고 다시 연결하십시오. 그러나 문서를 헤더에 넣으면 실제로 작은 부분을 변경하고 싶지 않으므로 프로젝트 재 구축의 상당 부분을 트리거하게됩니다.


1
이것은 이전의 7 가지 답변에서 제시되고 설명 된 포인트를 넘어서는 실질적인 것을 제공하지 않는 것 같습니다
gnat

1
이전 7 답변에서 @gnat은 헤더에 대한 코드를 선호합니다. 그리고 그것은 완전히 다른 주장을하고 있습니다.
Slava
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.