É melhor documentar funções no arquivo de cabeçalho ou no arquivo de origem?

77

Em linguagens que distinguem entre um arquivo "source" e "header" (principalmente C e C ++), é melhor documentar funções no arquivo de cabeçalho:

(saqueado de 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);

ou no arquivo de origem?

(roubado do 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)
{
...

Observe que algumas coisas são definidas apenas no cabeçalho, como structs, macros e static inline functions. Eu só estou falando sobre coisas que são declaradas em um arquivo de cabeçalho e definido em um arquivo de origem.

Aqui estão alguns argumentos que posso pensar. Eu estou inclinado a documentar no arquivo de origem, então meus argumentos "Pro-header" podem ser um pouco fracos.

Pro-cabeçalho:

  • O usuário não precisa do código-fonte para ver a documentação.
    • A fonte pode ser inconveniente, ou até impossível, para adquirir.
    • Isso mantém a interface e a implementação ainda mais distantes.

Pró-fonte:

  • Isso torna o cabeçalho muito mais curto, dando ao leitor uma visão panorâmica do módulo como um todo.
  • Ele associa a documentação de uma função à sua implementação, facilitando ver que uma função faz o que ela diz.

Ao responder, por favor, desconfie de argumentos baseados em quais ferramentas e "IDEs modernos" podem fazer. Exemplos:

  • Pro-header: o desdobramento de código pode ajudar a tornar os cabeçalhos comentados mais navegáveis ocultando os comentários.
  • Pro-source: o recurso Find this global definition do cscope leva você ao arquivo de origem (onde a definição é) ao invés do arquivo de cabeçalho (onde a declaração é).

Não estou dizendo que não faça tais argumentos, mas tenha em mente que nem todos se sentem tão à vontade com as ferramentas que você usa como você é.

    
por Joey Adams 15.06.2011 / 06:15
fonte

8 respostas

91

Minha opinião ...

  • Documente como usar a função no arquivo de cabeçalho ou mais precisamente perto da declaração.

  • Documente como a função funciona (se não for óbvio no código) no arquivo de origem ou, mais precisamente, próximo à definição.

Para a coisa do olho de pássaro no cabeçalho, você não precisa necessariamente da documentação que fecha - você pode documentar grupos de declarações de uma só vez.

Em termos gerais, o chamador deve estar interessado em erros e exceções (se puderem ser traduzidos à medida que se propagam através das camadas de abstração), de modo que devem ser documentados próximo às declarações relevantes.

    
por 15.06.2011 / 07:15
fonte
31

Se você vai usar uma ferramenta como Doxygen (observe no primeiro exemplo, que realmente parece um comentário do Doxygen porque começa com /** ) então isso não importa - o Doxygen irá olhar através do seu cabeçalho e dos arquivos fonte e encontrar todos os comentários para gerar a documentação.

No entanto, eu estaria mais inclinado a colocar os comentários da documentação nos cabeçalhos, onde estão as declarações. Seus clientes vão lidar com os cabeçalhos para fazer interface com seu software, os cabeçalhos são o que eles incluirão em seus próprios arquivos de origem e é aí que eles procurarão primeiro para ver como sua API se parece.

Se você olhar para a maioria das bibliotecas Linux, por exemplo, seu sistema de gerenciamento de pacotes Linux frequentemente tem um pacote que contém apenas os binários da biblioteca (para usuários "normais" que possuem programas que precisam da biblioteca) e você tem um "dev "pacote que contém os cabeçalhos da biblioteca. O código-fonte normalmente não é fornecido diretamente em um pacote. Seria muito complicado se você tivesse que obter o código-fonte de uma biblioteca em algum lugar para obter a documentação da API.

    
por 15.06.2011 / 09:26
fonte
11

Resolvemos esse problema (há cerca de 25 anos) criando vários #defines (por exemplo, públicos, privados, etc., que foram resolvidos para < nothing >) que puderam ser usados no arquivo de origem e foram verificados por um script awk (horrores!) para gerar automaticamente os arquivos. Isso significa que todos os comentários residiam na origem e foram copiados (quando apropriado) no arquivo .h gerado. Eu sei que é bastante Old School, mas simplificou muito esse tipo de documentação inline.

    
por 15.06.2011 / 06:31
fonte
5

Na minha opinião (bastante limitada e tendenciosa), sou o modo de pensar do código pró-fonte. Quando eu faço pedaços em C ++, costumo editar o arquivo de cabeçalho uma vez e depois nunca mais volto a olhar para ele.

Quando coloco a documentação no arquivo de origem, sempre a vejo quando estou editando ou lendo códigos. Eu acho que é uma coisa de hábito.

Mas isso é só comigo ...

    
por 15.06.2011 / 06:21
fonte
5

Comentários não são documentação. A documentação de uma função pode normalmente ser de 2 K de texto, possivelmente com diagramas - consulte, por exemplo, a documentação de funções no Windows SDK. Mesmo que o seu comentário para o documento permita tal coisa, você estará tornando o código que contém o comentário ilegível. Se você quiser produzir documentação, use um processador de texto.

    
por 15.06.2011 / 08:56
fonte
5

Assumindo que este é um código dentro de um projeto maior (onde os desenvolvedores estarão se movendo entre a origem e os cabeçalhos com freqüência) , e fornecendo isso não é uma biblioteca / middleware, onde outros podem não ter acesso à fonte, eu achei que isso funciona melhor ...

  • Cabeçalhos:
    comentários de linha do Terse 1-2, somente se eles forem necessários.
    Às vezes os comentários acima de um grupo de funções relacionadas também são úteis.
  • Fonte:
    Documentação sobre API diretamente acima da função (texto simples ou doxygen, se preferir) .
  • Mantenha os detalhes da implementação, relevantes apenas para um desenvolvedor que esteja modificando o código no corpo da função.

A principal razão para isso é manter os comentários perto do código. Percebi que os documentos nos cabeçalhos tendem a ficar fora de sincronia com as alterações no código com mais frequência (claro que não deveriam, mas eles fizeram no nosso projeto, pelo menos) . Também os desenvolvedores podem adicionar documentação na parte superior das funções quando fizerem alguma alteração, mesmo se houver documentos de cabeçalho ... em algum outro lugar. Causar duplas ou informações úteis apenas para estar em uma das cadeias de documentos.

É claro que você pode escolher uma convenção e garantir que todos os desenvolvedores sigam, eu achei a convenção acima da mais natural-fit e causa menos problemas para manter.

Por último, para projetos grandes - há uma inclinação não para fazer pequenas correções em um cabeçalho quando você sabe que isso pode fazer com que centenas ou milhares de arquivos sejam re-compilados quando outros atualizarem a versão controle - retardando erros de divisão também.

    
por 12.10.2015 / 15:15
fonte
4

Se os participantes do seu código-fonte (digamos, uma pequena biblioteca) consistir em "usuários" (desenvolvedores que usarão a funcionalidade da sua biblioteca sem se envolver em sua implementação) e "desenvolvedores" (você e outros desenvolvedores que implementarão a biblioteca), em seguida, coloque as "informações dos usuários" no cabeçalho e "nota de implementação" na fonte.

No que diz respeito ao desejo de não alterar os arquivos de cabeçalho mais do que é absolutamente necessário - suponho que se a sua biblioteca não estiver "em um fluxo louco de mudanças", a "interface" e a "funcionalidade" não mudarão muito e nem os comentários de cabeçalho devem mudar com muita frequência. Por outro lado, os comentários do código-fonte terão que ser mantidos sincronizados ("fresh") com o código-fonte.

    
por 15.06.2011 / 06:33
fonte
1

O objetivo de usar o doxygen é que você gera documentação e o torna acessível em outro lugar. Agora toda essa documentação nos cabeçalhos é apenas lixo, o que torna mais difícil identificar rapidamente a declaração de função necessária e, talvez, suas sobrecargas. Um comentário de linha é o máximo que deveria ir até lá, mas mesmo isso é uma má prática. Porque se você alterar a documentação na fonte, você recompila essa fonte e revincula. Mas se você colocar docs no cabeçalho, realmente não vai querer mudar nada, pois isso desencadeará uma parte significativa da reconstrução do projeto.

    
por 05.07.2017 / 11:25
fonte

Tags