Qual é a diferença entre os estilos K&R e One True Brace Style (1TBS)?

48

Eu li o artigo da Wikipedia sobre estilos de recuo , mas ainda não entendo. Qual é a diferença entre K&R e 1TBS?

GavinR
fonte
Li em algum lugar que o estilo em K&R era governado por considerações de espaço - ou seja, para reduzir o espaço vertical que o código ocupava no livro.
ChrisF
@ChrisF também reduz o espaço vertical na tela. Quando tínhamos 80 terminais de linha col x 25, valeu a pena!
Martin Beckett
7
Maçã de "goto falhar" é um grande exemplo de um erro grave que certamente teria sido evitado usando 1TBS: imperialviolet.org/2014/02/22/applebug.html
4
O bug da Apple também poderia ter sido evitado, colocando a declaração em uma única linha, revisando, usando um verificador de código morto ou usando uma linguagem sensível ao recuo.
Cees Timmerman
11
@CeesTimmerman, .. or having tests ... #
thoni56:

Respostas:

76

A maior diferença entre K & R eo One True Brace Style (1TBS) é que no 1TBS, todos if, else, while, e fordeclarações têm abertura e fechamento de chaves, mesmo que eles não são necessários. O objetivo é facilitar a inserção de novas instruções e saber exatamente como elas serão agrupadas.

Como um exemplo:

K&R:

int i;
for (i = 0; i < 10; i++)
  printf("Hi.");

1TBS:

int i;
for (i = 0; i < 10; i++) {
  printf("Hi");
}
Thomas Owens
fonte
20

K&R é assim:

if (x) 
    a();
else {
    b();
    c();
}

Ou seja: chaves usadas apenas quando necessário, abrindo a chave na mesma linha que a instrução de controle, fechando a chave em sua própria linha.

O "estilo de colchete verdadeiro" (1TBS ou OTBS) transforma uma única instrução controlada em uma instrução composta, colocando-a entre colchetes:

if (x) {
    a();
} else {
    b();
    c();
}

O estilo Allman vai um pouco além de 1 TB e força o espaçamento vertical ao colocar a chave de abertura em uma linha também:

if (x) 
{
    a();
}
else 
{
    b();
    c();
}

Editar:

Ainda estou tentando descobrir exatamente como isso se qualifica como "arrogante" em dizer "Dennis Ritchie era um cara extremamente inteligente que não apenas inventou uma boa linguagem, mas também criou um estilo de cinta muito bom".

Para aqueles que insistem que está sendo arrogante de qualquer maneira, aqui está um pequeno desafio: vá para Sourceforge, Github (etc.) e escolha projetos usando o estilo K&R. Analise seus registros de bugs e confirmações e tente encontrar um único bug causado pelo estilo de chave que eles usavam.

Se você não quer fazer tanto trabalho, tente fazer uma análise estatística simples. Compare projetos usando diferentes estilos de chaves e veja se é possível mostrar "bimodalidade" - uma diferença estatisticamente significativa nas contagens de bugs (gravidade, etc.) que se correlaciona com o estilo de chaves.

Eu fiz as duas coisas há alguns anos atrás e não consegui encontrar um único bug que pudesse atribuir a estilos estimulantes, nem encontrei nada que se aproximasse de uma correlação estatisticamente significativa entre os dois. Em média, aqueles que utilizam K & R órtese tinha ligeiramente menos bugs, mas a diferença foi muito pequena demais para se qualificar como estatisticamente significativo.

Desde que foi apresentado, vou comentar sobre a situação com macros de múltiplas instruções. Uma macro que inclui várias instruções, mas não as envolve com chaves, possui um bug. Meu trabalho não é escrever código que cubra esse bug. Muito pelo contrário, meu trabalho é encontrar e erradicar esse bug o mais rápido possível.

Escrever código na esperança de encobrir os bugs para que eles não sejam diagnosticados e não consertados é absolutamente ruim. Chame isso de arrogante, se quiser, mas não vejo isso nem perto de negociável. Os erros devem ser encontrados e corrigidos, não encobertos. Quanto mais tempo existir, maior será a probabilidade de que eles se tornem muito mais difíceis e caros de consertar.

Jerry Coffin
fonte
11
Excluíram todos os comentários, pois eles haviam diminuído para discussões e ruídos. Se você tem um ponto válido, poste-o como resposta. Se você quiser uma discussão, leve-a para o chat
ChrisF
8
o 1tbs não coloca o} e mais em uma linha? Economizar espaço vertical e preservar a maravilhosa simetria é o ponto!
Martin Beckett
4
@Jerry - bem qualquer bom guerra santa precisa de alguns cismas ;-)
Martin Beckett
6
Goto falhar; Goto falhar;
Jamie Pate
9
Sim para acompanhar o comentário de @ JamiePate, que é o bug do SSL da Apple analisado aqui . Existe uma ifinstrução com instruções recuadas depois, parecendo que ambas são executadas condicionalmente. Mas não há aparelho! A segunda declaração está realmente além do ife sempre será executada, portanto, o bug.
Colin D Bennett
9

O problema, em geral com o estilo de chave KR, está na refatoração de código. Ao mover o código, é fácil esquecer que não há chaves em torno de algo, mova-o incorretamente (ou mova algo sob ele, pensando que é executado condicionalmente) e depois coça a cabeça quando algo não funcionar mais ou seja infeliz e esteja uma área de código pouco testada e o bug passa despercebido até que um chapéu preto encontre uma maneira de explorá-lo. Uma rápida visita ao depurador encontra facilmente o problema se você perceber, mas se não ...

Justin Swanhart
fonte
2
isso parece meramente repetir o argumento exposto e explicado em respostas anteriores #
396
11
Não acho que as outras respostas expliquem exatamente como o problema surge no código cotidiano. Eles explicam o que é OTB, mas não porque é realmente importante. Os comentários podem tratar disso, mas não as respostas.
Justin Swanhart