Razão para colocar o tipo de função e o nome do método em diferentes linhas em C

16

Comecei em uma empresa e um dos comentários de estilo na minha primeira revisão de código foi que o tipo de retorno e o nome do método deveriam estar em linhas diferentes. Por exemplo, isso

void foo() {
}

deveria ser isso

void
foo() {
}

Eu sempre usei o primeiro estilo e fiquei imaginando se existe algum motivo além da preferência pessoal por que as pessoas usam o segundo estilo? Eu não acho que o primeiro prejudique a legibilidade. Um é mais comum que o outro com programadores C e grandes projetos de código aberto?

gsingh2011
fonte
3
Isso está no padrão GNU (não necessariamente dizendo que é uma coisa boa, o estilo de reforço é estranho). gnu.org/prep/standards/standards.html#Formatting
Gauthier

Respostas:

19

estava se perguntando se existe algum motivo além da preferência pessoal por que as pessoas usam o segundo estilo?

Esse é um estilo que era popular nos primórdios do C, então o motivo pode ser apenas o modo como eles fazem isso há muito tempo, eles têm muito código parecido com isso e é isso que todo mundo está acostumado. Não tanto a preferência pessoal como o impulso corporativo.

Outro motivo é que os nomes das funções sempre começam na primeira coluna. Os tipos de retorno variam em tamanho e podem ser um pouco complexos - colocar o tipo em sua própria linha facilita a localização do nome da função.

Se a empresa tiver um estilo definido, eles também poderão ter um documento de padrões de codificação. Peça por isso. Isso pode explicar o (s) motivo (s) dessa escolha e ter uma cópia ajudará a evitar problemas semelhantes em análises futuras.

Caleb
fonte
2
Eu acho que também está conectado ao limite de 80 caracteres ainda usado e defendido por muitos programadores. Se você deseja ter um limite de 80 caracteres e usar nomes descritivos de métodos / funções, é necessário fazer alguns compromissos. Dividir o cabeçalho do método é um deles.
21813 Sulthan
A declaração também pode ser mais longa - pense em diferentes modificadores (não padrão), como chamar identificadores de convenção (stdcall, etc.), informações sobre visibilidade de símbolo (DLLEXPORT) ou __attributes. E então, ao olhar para C ++, você pode ter tipos de retorno relativamente complexos, então em algum lugar pode ser necessário adicionar uma quebra de linha.
Johannes
@ Sulthan Não são apenas os programadores (que estão acostumados a janelas de terminal e usando editores de terminal), curiosamente. Na tipografia, 72 a 80 caracteres geralmente são considerados a largura ideal para uma coluna de texto em termos de legibilidade. (Daí por TeX e seus derivados padrão para o que algumas pessoas consideram colunas estranhamente estreitos.)
JAB
1
@ JAB Na verdade, agora isso. Sei também que ler um texto justificado e ler o código-fonte são duas coisas muito diferentes e não têm quase nada em comum; portanto, a largura ideal é irrelevante.
Sulthan 22/09
1
"Outro motivo é que os nomes das funções sempre começam na primeira coluna [e são] mais fáceis de encontrar." E isso é muito mais do que apenas um benefício visual: agora podemos procurar a expressão regular ^start_of_a_long_funce ser levados imediatamente para a função que estamos procurando.
Underscore_d
7

Essa é praticamente a única regra de formatação de código que encontrei realmente causa um impacto notável na legibilidade e não exige quase nenhum esforço (supondo que o seu editor de código não inicie uma briga com você).

É bom o design da linguagem de programação para que os nomes apareçam em uma posição consistente nas declarações / definições. O raciocínio é direto: você tem uma boa âncora visual (uma cinta encaracolada ou apenas um recuo pendurado) que pode ser usada para encontrar imediatamente o início do nome. Você não precisa analisar o idioma ao digitalizar um arquivo para encontrar o nome.

É o mesmo que quando você está formatando um documento: quando você inicia uma nova seção, coloca o nome na frente em negrito - geralmente em sua própria linha - não enterrado em algum lugar, indiferenciado, em uma frase longa.

O C inicial tinha assinaturas muito concisas: os tipos de retorno eram opcionais e os tipos de argumento foram declarados após a assinatura. Os nomes também tendem a ser muito curtos. Isso mitigou o impacto de um tipo de retorno ocasional compensar o nome.

double dot(x, y);

Ainda é bastante digerível.

O C ++ tornou isso um pouco pior. Ele moveu as especificações de tipo de argumento para assinaturas, tornando as assinaturas mais longas. Essa sintaxe foi adotada posteriormente durante a padronização de C.

static struct origin *find_origin(struct scoreboard *sb,
                  struct commit *parent,
                  struct origin *origin)

é menos digerível, mas não é tão ruim. (Trecho do Git)

Agora considere as práticas de programação modernas com nomes longos e descritivos e tipos parametrizados e veja como essa escolha se tornou desastrosa. Um exemplo de um cabeçalho Boost:

template <class A1, class A2, class A3, class A4, class A5, class A6>
inline typename normalise<policy<>, A1, A2, A3, A4, A5, A6>::type make_policy(const A1&, const A2&, const A3&, const A4&, const A5&, const A6&)
{ 
   typedef typename normalise<policy<>, A1, A2, A3, A4, A5, A6>::type result_type;
   return result_type(); 
}

Se você estiver escrevendo código genérico, assinaturas como essa nem são fora do comum. Você pode encontrar exemplos de casos muito piores do que isso sem se esforçar demais.

C, C ++ e seus derivados, Java e C #, parecem ser as exceções a ter declarações / definições legíveis. Seus predecessores e colegas populares (Fortran, ALGOL, Pascal) colocaram nomes antes dos tipos de resultados e, felizmente, muitos de seus sucessores (Go, Scala, TypeScript e Swift, para citar alguns) também escolheram sintaxes mais legíveis.

user2313838
fonte
1
Seja grato por não precisar escrever programas Fortran. Eu lhe digo, declarar separadamente os argumentos da sua função vai lhe dar nos nervos muito rapidamente quando você for forçado a fazê-lo. Especialmente ao tentar ler uma assinatura de função para entender quais argumentos ela espera: o C ++ coloca os tipos exatamente onde eles pertencem, o Fortran obriga a iniciar uma pesquisa visual de palavras-chave pelo nome da variável para determinar seu tipo.
cmaster - reinstate monica
2
Colocar os tipos na declaração de função foi realmente inventado pelo C ++? Eu nunca tinha ouvido falar disso, e estou lutando para encontrar citações.
Underscore_d
1
Veja o Desenvolvimento da Linguagem C . Na seção Padronização, Ritchie menciona que a sintaxe foi emprestada do C ++.
user2313838
5

Conheci esse estilo pela primeira vez em 19 anos, trabalhando com C & C ++. Estava bastante confuso sobre como alguém poderia inventar essa coisa má.

O único ponto positivo (potencialmente) positivo que pude encontrar é que você pode encontrar a definição de função usando grep ^ FuncName. Pode ser um fator relevante, décadas atrás, em algumas comunidades reais de ódio por ferramentas ... No local em que vi, era aplicado ao C ++ e às funções dos membros da classe, que matam até esse atributo.

Adivinhe a minha opinião. :)

Balog Pal
fonte
1
grep -P '^(\w+::)?FuncName'
Kyle Strand
Sim, os tipos de classe nos nomes das funções não impedem o uso disso. Portanto, ainda é útil para navegar rapidamente pelos arquivos de origem. Quanto à aparência do mal ou o que quer que seja, opiniões são opiniões: cheguei a pensar que parece melhor.
underscore_d