Estou lendo algumas notas de aula do meu professor de C ++ e ele escreveu o seguinte:
- Usar recuo // OK
- Nunca confie na precedência do operador - Sempre use parênteses // OK
- Sempre use um bloco {} - mesmo para uma única linha // não está bem , por que ???
- Objeto Const no lado esquerdo da comparação // OK
- Use não assinado para variáveis que são> = 0 // truque legal
- Defina o Ponteiro como NULL após a exclusão - Proteção contra exclusão dupla // não é ruim
A terceira técnica não está clara para mim: o que eu ganharia colocando uma linha em uma { ... }
?
Por exemplo, pegue este código estranho:
int j = 0;
for (int i = 0 ; i < 100 ; ++i)
{
if (i % 2 == 0)
{
j++;
}
}
e substitua-o por:
int j = 0;
for (int i = 0 ; i < 100 ; ++i)
if (i % 2 == 0)
j++;
Qual é o benefício de usar a 1ª versão?
for (unsigned i = 100; i >= 0; --i)
.(i % 2 == 0)
contradiz (2). Você está confiando na precedência do operador, e é claro((i % 2) == 0)
que o significado é mais do que isso(i % (2 == 0))
. Eu classificaria a regra 2 como "um sentimento válido, mas 'sempre' está errado".Respostas:
Vamos tentar também modificar
i
quando incrementamosj
:Ah não! Vindo do Python, isso parece ok, mas na verdade não é, pois é equivalente a:
Claro, esse é um erro bobo, mas que até um programador experiente poderia cometer.
Outro motivo muito bom é apontado na resposta de ta.speot.is .
Um terceiro que eu consigo pensar é o aninhado
if
:Agora, suponha que você queira agora
doSomethingElse()
quandocond1
não for atendido (novo recurso). Assim:o que está obviamente errado, uma vez que os
else
associados ao interiorif
.Edit: Uma vez que isso está recebendo alguma atenção, vou esclarecer minha opinião. A pergunta que eu estava respondendo é:
Que eu descrevi. Existem alguns benefícios. Mas, IMO, regras "sempre" nem sempre se aplicam. Então eu não apoio totalmente
Não estou dizendo que sempre use um
{}
bloco. Se é uma condição e comportamento bastante simples, não. Se você suspeitar que alguém possa entrar mais tarde e alterar seu código para adicionar funcionalidade, faça.fonte
i++
antesj++
, as duas variáveis ainda estarão no escopo quando usadas.i++;
de uma maneira que mostre imediatamente que não faz parte do loop. (No passado, isso pode ter sido um argumento razoável, e eu vi esses problemas cerca de 20 anos atrás desde então...)É muito fácil alterar acidentalmente o fluxo de controle com comentários, se você não usar
{
e}
. Por exemplo:Se você comentar
do_something_else()
com um único comentário de linha, você terminará com o seguinte:Compila, mas
must_always_do_this()
nem sempre é chamado.Tivemos esse problema em nossa base de código, onde alguém havia desabilitado algumas funcionalidades muito rapidamente antes do lançamento. Felizmente, nós o pegamos na revisão de código.
fonte
must_always_do_this();
será executado se você comentar // do_something_else ();if(debug) \n //print(info);
. Basicamente tirou uma biblioteca inteira.Fortunately we caught it in code review.
Ai! Isso parece tão errado.Fortunately we caught it in unit tests.
seria muito melhor!Tenho minhas dúvidas quanto à competência do palestrante. Considerando seus pontos:
(b*b) - ((4*a)*c)
? Algumas precedências são óbvias (ou deveriam ser), e os parênteses extras apenas aumentam a confusão. (Por outro lado, você deve usar os parênteses em casos menos óbvios, mesmo que saiba que eles não são necessários.){
não é tão visível, então é melhor assumir que está sempre lá. No segundo, no entanto, eu (e a maioria das pessoas com quem trabalhei) não tenho nenhum problema em omitir os aparelhos para uma única declaração. (Desde que, é claro, que a indentação seja sistemática e que você use esse estilo de forma consistente. (E muitos programadores muito bons, escrevendo código muito legível, omitem os chavetas, mesmo quando formatam a primeira maneira))if ( NULL == ptr )
são feias o suficiente para dificultar a legibilidade. Escreva as comparações intuitivamente. (O que em muitos casos resulta na constante à direita.) Seus 4 são maus conselhos; qualquer coisa que torne o código não natural o torna menos legível.int
está reservado para casos especiais. Para programadores experientes em C e C ++, o uso deunsigned
operadores de bits de sinais. O C ++ não possui um tipo cardinal real (ou qualquer outro tipo de subintervalo eficaz);unsigned
não funciona para valores numéricos, devido às regras de promoção. Valores numéricos nos quais nenhuma operação aritmética faria sentido, como números de série, poderiam ser presumivelmenteunsigned
. Eu argumentaria contra, no entanto, porque envia a mensagem errada: operações bit a bit também não fazem sentido. A regra básica é que tipos integrais sãoint
, a menos que haja um motivo significativo para o uso de outro tipo.delete this;
é frequentemente o caso mais frequente (e você não pode definirthis
aNULL
), e de outra forma, a maioriadelete
estão em destruidores, para que você não pode acessar o ponteiro depois de qualquer maneira. E configurá-lo paraNULL
não faz nada com outros ponteiros flutuando. Definir o ponteiro sistematicamente paraNULL
dá uma falsa sensação de segurança e realmente não compra nada para você.Veja o código em qualquer uma das referências típicas. Stroustrup viola todas as regras que você deu, exceto a primeira, por exemplo.
Eu sugiro que você encontre outro professor. Alguém que realmente sabe do que está falando.
fonte
delete this
, é mais comum do que já vi? Eu não costumo pensar que definir um ponteiro para NULL após o uso seja algo ruim de fazer, além do YMMV. Talvez seja só eu, mas a maioria das diretrizes dele não parece tão ruim.if (ptr = NULL)
menos que você o escreva comoif ((ptr = NULL))
. Tenho que concordar com James Kanze que a feiúra de terNULL
primeiro o torna um NÃO definitivo para mim.unsigned
indica uma aspiração por parte do programador de que a variável deve representar apenas números positivos. Misturar com números assinados geralmente causará um aviso do compilador, provavelmente o que o professor pretendia.size_t
, qualquer um?Todas as outras respostas defendem a regra do seu professor 3.
Deixe-me dizer que concordo com você: a regra é redundante e eu não a aconselharia. É verdade que teoricamente evita erros se você sempre adiciona colchetes. Por outro lado, nunca encontrei esse problema na vida real : ao contrário do que outras respostas sugerem, nunca esqueci de adicionar os colchetes quando eles se tornaram necessários. Se você usar o recuo adequado, torna-se imediatamente óbvio que você precisará adicionar colchetes depois que mais de uma instrução for recuada.
A resposta do “Componente 10”, na verdade, destaca o único caso concebível em que isso realmente pode levar a um erro. Mas, por outro lado, a substituição de código por meio de expressão regular sempre exige muito cuidado.
Agora, vamos olhar para o outro lado da medalha: existe uma desvantagem em usar sempre colchetes? As outras respostas simplesmente ignoram esse ponto. Mas não é uma desvantagem: ele ocupa muito espaço na tela vertical, e este por sua vez, pode fazer o seu código ilegível, porque isso significa que você tem que mover-se mais do que o necessário.
Considere uma função com muitas cláusulas de guarda no início (e sim, o código a seguir é ruim para C ++, mas em outros idiomas isso seria uma situação bastante comum):
Este é um código horrível, e eu argumento fortemente que o seguinte é muito mais legível:
Da mesma forma, loops aninhados curtos se beneficiam da omissão dos colchetes:
Compare com:
O primeiro código é conciso; o segundo código está inchado.
E sim, isso pode ser atenuado até certo ponto , colocando a chave de abertura na linha anterior. Mas isso ainda seria menos legível que o código sem colchetes.
Resumindo: não escreva códigos desnecessários que ocupam espaço na tela.
fonte
if (a == nullptr) { throw null_ptr_error("a"); }
como uma linha.A base de código em que estou trabalhando é repleta de código por pessoas com aversão patológica a aparelhos, e para as pessoas que aparecem mais tarde, realmente pode fazer a diferença na manutenção.
O exemplo problemático mais frequente que encontrei é o seguinte:
Portanto, quando eu aparecer e desejar adicionar uma declaração, eu posso facilmente terminar com isso se não for cuidadoso:
Tendo em conta que é preciso ~ 1 segundo para adicionar chaves e você pode salvar no mínimo alguns minutos confusos depuração, por que você nunca não ir com a opção reduziu-ambigüidade? Parece uma economia falsa para mim.
fonte
if(really long...editor){ do_foo;}
ajudando a evitar esse caso? Parece que o problema ainda seria o mesmo. Pessoalmente, prefiro evitar chaves quando não for necessário, mas isso não tem nada a ver com o tempo necessário para escrevê-las, mas com a legibilidade reduzida. devido às duas linhas extras no código.Meu 2c:
Obviamente
Eu não usaria as palavras "nunca e" sempre ", mas em geral vejo essa regra sendo útil. Em alguns idiomas (Lisp, Smalltalk) isso não é problema.
Eu nunca faço isso e nunca tive um único problema, mas posso ver como isso pode ser bom para os alunos, especialmente. se eles estudaram Python antes.
Condições de Yoda? Não por favor. Dói a legibilidade. Basta usar o nível máximo de aviso ao compilar seu código.
ESTÁ BEM. Engraçado o suficiente, ouvi Stroustrup discordar.
Mau conselho! Nunca tenha um ponteiro que aponte para um objeto excluído ou inexistente.
fonte
unsigned
está quebrado", um dos problemas é que, quando o C ++ compara tipos assinados e não assinados de tamanho semelhante, ele se converte no não assinado antes de fazer a comparação. O que resulta em uma mudança de valor. Converter para o assinado não seria necessariamente muito melhor; a comparação realmente deve ocorrer "como se" os dois valores fossem convertidos em um tipo maior que pudesse representar todos os valores em ambos os tipos.unsigned
. Tenho certeza que ele não tem nenhum problema emexp(double)
retornar um valor maior queMAX_INT
:-). Mas mais uma vez, o verdadeiro problema são as conversões implícitas.int i = exp( 1e6 );
é perfeitamente válido em C ++. Stroustrup, na verdade, propôs a depreciação de conversões implícitas com perdas a certa altura, mas o comitê não estava interessado. (Uma questão interessante: seriaunsigned
->int
ser considerado lossy Eu considero ambos.unsigned
->int
eint
->unsigned
lossy que seria um longo caminho a fazer.unsigned
OKé mais intuitivo e facilmente compreensível. Isso torna clara a intenção.
E garante que o código não seja interrompido quando um novo usuário pode, sem saber, sentir falta dele
{
,}
enquanto adiciona uma nova instrução de código.fonte
Makes the intent clear
+1, esse é provavelmente o motivo mais conciso e preciso.Para adicionar às sugestões mais sensatas acima, um exemplo que encontrei ao refatorar algum código de onde isso se torna crítico foi o seguinte: Eu estava alterando uma base de código muito grande para alternar de uma API para outra. A primeira API teve uma chamada para definir o ID da empresa da seguinte maneira:
considerando que a substituição precisava de duas chamadas:
Comecei a mudar isso usando expressões regulares que foram muito bem-sucedidas. Também passamos o código pelo astyle , o que realmente o tornou muito mais legível. Então, no meio do processo de revisão, descobri que, em algumas circunstâncias condicionais, isso estava mudando:
Para isso:
o que claramente não é o que era necessário. Eu tive que voltar ao início, tratando a substituição completamente dentro de um bloco e alterando manualmente qualquer coisa que acabasse parecendo pateta (pelo menos não seria incorreta).
Percebo que o estilo agora tem a opção
--add-brackets
que permite adicionar colchetes onde não há nenhum e eu recomendo isso se você se encontrar na mesma posição que eu.fonte
#define FOO() func1(); \ func2();
(com uma quebra de linha após a barra invertida), o mesmo vale para pesquisa e substituição. Dito isto, vi "sempre use chaves" avançado como regra de estilo, precisamente porque evita que você envolva todas as suas macros de múltiplas instruçõesdo .. while(0)
. Mas eu discordo.inline
), provavelmente deve procurar que funcionem o mais parecido possível com uma função, usando odo { ... } while(0)
truque, se necessário (e muitos parênteses extras. Mas isso ainda não impedi-lo de usar aparelho em todos os lugares, se esse for o estilo da casa. (FWIW: Trabalhei em locais com estilos variados de casas, cobrindo todos os estilos discutidos aqui. Nunca achei que isso fosse um problema sério).Estou usando em
{}
qualquer lugar, exceto em alguns casos em que é óbvio. Linha única é um dos casos:Pode machucá-lo quando você adiciona algum método antes de retornar. O recuo indica que o retorno está sendo executado quando a condição é atendida, mas sempre retornará.
Outro exemplo em C # com o uso de declaração
que é equivalente a
fonte
using
declaração e você não precisa :) :)using
).O exemplo mais pertinente em que consigo pensar:
Com o qual
if
oelse
par será emparelhado? A indentação implica que o externoif
recebe oelse
, mas não é assim que o compilador o verá; o interiorif
receberá oelse
e o exteriorif
não. Você precisaria saber isso (ou vê-lo se comportar dessa maneira no modo de depuração) para descobrir por inspeção por que esse código pode estar falhando em suas expectativas. Fica mais confuso se você conhece Python; nesse caso, você sabe que o recuo define os blocos de código; portanto, você esperaria que ele fosse avaliado de acordo com o recuo. O C #, no entanto, não dá a mínima para o espaço em branco.Agora, dito isso, não concordo particularmente com esta regra "sempre use colchetes". Torna o código muito verticalmente barulhento, reduzindo a capacidade de lê-lo rapidamente. Se a declaração for:
... então deve ser escrito assim. A afirmação "sempre use colchetes" soa como "sempre envolva operações matemáticas entre parênteses". Que iria transformar a afirmação muito simples
a * b + c / d
para((a * b) + (c / d))
, introduzindo a possibilidade de perder um close-paren (a ruína de um codificador muitos), e para quê? A ordem das operações é bem conhecida e aplicada, portanto os parênteses são redundantes. Você usaria apenas parênteses para impor uma ordem de operações diferente da que seria normalmente aplicada:a * (b+c) / d
por exemplo. Chaves de bloco são semelhantes; use-os para definir o que você deseja fazer nos casos em que difere do padrão e não seja "óbvio" (subjetivo, mas geralmente bastante senso comum).fonte
else
o primeiro aoif
invés do segundo. Por favor, remova o voto negativo.Ao analisar as respostas, ninguém declarou explicitamente o tipo de prática que eu tenho o hábito de contar a história do seu código:
Torna-se:
Colocar
j++
na mesma linha que o if deve sinalizar para mais alguém: "Eu só quero que esse bloco seja incrementadoj
" . De coursethis só vale a pena se a linha é tão simplista quanto possível, porque colocar um ponto de interrupção aqui, como peri menciona, não vai ser muito útil.Na verdade, eu acabei de percorrer parte da API do Twitter Storm que possui esse 'tipo' de código em java, eis o snippet relvant do código de execução, na página 43 desta apresentação de slides :
O bloco de loop for tem duas coisas, então eu não incorporaria esse código. Ou seja, nunca :
É horrível e nem sei se funciona (como pretendido); não faça isso . Novas linhas e chaves ajudam a distinguir trechos de código separados, mas relacionados, da mesma forma que uma vírgula ou um ponto e vírgula na prosa. O bloco acima é uma sentença muito longa, com algumas cláusulas e outras declarações que nunca quebram ou pausam para distinguir partes separadas.
Se você realmente deseja telegrafar para outra pessoa, é um trabalho de apenas uma linha, use um operador ou
?:
formulário ternário :Mas isso está se aproximando do code-golf, e acho que não é uma boa prática (não está claro para mim se devo colocar o j ++ em um lado
:
ou não). NB: Eu nunca executei um operador ternário em C ++ antes, não sei se isso funciona, mas existe .Em resumo:
Imagine como o seu leitor (ou seja, a pessoa que mantém o código) interpreta sua história (código). Deixe o mais claro possível para eles. Se você sabe que o aluno / programador iniciante está mantendo isso, talvez deixe o maior número
{}
possível, só para não ficar confuso.fonte
for
loop em uma única linha, por que isso não deveria funcionar? Funciona pelo mesmo motivo que você pode omitir os chavetas; newline simplesmente não é significativo em C ++. (3) Seu exemplo de operador condicional, além de horrível, é C ++ inválido.Porque quando você tem duas declarações sem
{}
, é fácil perder um problema. Vamos assumir que o código se parece com isso.Parece bem. O problema com isso é realmente fácil de perder, especialmente quando a função que contém o código é muito maior. O problema é que
goto fail
é executado incondicionalmente. Você pode facilmente imaginar o quão frustrante isso é (fazendo você perguntar por que o últimohash_update
sempre falha, afinal tudo parecehash_update
funcionar bem).No entanto, isso não significa que sou a favor de adicionar em
{}
todos os lugares (na minha opinião, ver{}
todos os lugares é irritante). Embora possa causar problemas, isso nunca aconteceu em meus próprios projetos, pois meu estilo de codificação pessoal proíbe condicionais sem{}
que eles não estejam na mesma linha (sim, eu concordo que meu estilo de codificação não é convencional, mas eu gosto e eu use o estilo de código do projeto ao contribuir para outros projetos). Isso torna o código a seguir correto.Mas não o seguinte.
fonte
Isso torna seu código mais legível, definindo claramente o escopo de seus loops e blocos condicionais. Também evita erros acidentais.
fonte
wrt 6: É mais seguro, pois excluir um ponteiro nulo não é necessário. Portanto, se você acidentalmente seguir esse caminho duas vezes, não fará com que a corrupção da memória libere a memória livre ou que tenha sido alocada para outra coisa.
Esse é o maior problema com objetos estáticos de escopo de arquivo e singletons que não têm vida útil muito clara e que são conhecidos por serem recriados após serem destruídos.
Na maioria dos casos, você pode evitar a necessidade disso usando auto_ptrs
fonte
NULL
após excluí-lo. SeNULL
for um valor correto para o ponteiro nessas circunstâncias; por exemplo, o ponteiro aponta para um valor em cache eNULL
indica um cache inválido. Mas quando você vê alguém definindo um ponteiro paraNULL
como a última linha de um destruidor, você quer saber se ele sabe C ++).Gosto da resposta aceita de Luchian; na verdade, aprendi da maneira mais difícil que ele está certo, então sempre uso aparelho, mesmo para blocos de linha única. No entanto, pessoalmente, faço uma exceção ao escrever um filtro, como você está no seu exemplo. Este:
parece confuso para mim. Ele separa o loop for e a instrução if em ações separadas, quando realmente sua intenção é uma ação única: contar todos os números inteiros divisíveis por 2. Em uma linguagem mais expressiva, isso pode ser escrito como:
Em idiomas que não têm fechamento, o filtro não pode ser expresso em uma única instrução, mas deve ser um loop for seguido por uma instrução if. No entanto, ainda é uma ação na mente do programador, e acredito que isso deve se refletir no código, assim:
fonte
for (int i = 0; i < 100; i += 2);
, por uma questão de continuar a discussão sobre indentação ;-) Provavelmente há uma briga de coelhos separada que poderíamos ter, como "melhor" para expressar a lógica "para cadai
um em um determinado intervalo com uma certa propriedade" em C ++ sem loop, usando alguma combinação de pesadelo de algoritmos padrãofilter_iterator
e / oucounting_iterator
.i
um em um determinado intervalo com uma certa propriedade". Geralmente, no SO, as pessoas são muito rápidas em ignorar a pergunta real em favor de uma abordagem completamente diferente do exemplo dado. Mas o recuo é importante , por isso não faz ;-)Uma opção para ajudar a evitar os erros descritos acima é alinhar o que você deseja que aconteça quando não usa aparelho. Torna muito mais difícil não perceber os erros quando você tenta modificar o código.
fonte
else
não está associado a umif
.Se você é um compilador, não faz diferença. Ambos são iguais.
Mas para os programadores, o primeiro é mais claro, fácil de ler e menos propenso a erros.
fonte
{
em sua própria linha, de qualquer maneira.Outro exemplo de adição de chaves. Uma vez eu estava procurando por um bug e encontrei esse código:
Se você ler o método linha por linha, notará que existe uma condição no método que retorna se não for verdadeira. Mas, na verdade, parece com outros 100 manipuladores de eventos simples que definem algumas variáveis com base em algumas condições. E um dia o Fast Coder entra e adiciona uma declaração de configuração de variável adicional ao final do método:
Como resultado, o SetAnotherVariableUnconditionnaly é executado quando o SomeConditionIsMet (), mas o cara rápido não percebeu, porque todas as linhas são quase de tamanho semelhante e mesmo quando a condição de retorno é recuada verticalmente, não é tão perceptível.
Se o retorno condicional for formatado assim:
é muito perceptível e o Fast Coder o encontrará rapidamente.
fonte
return
instrução destacada pela sintaxe no corpo de uma função antes de adicionar algo a ela, não deixe o codificador rápido se aproximar do seu código. Você não impedirá que esse tipo de pessoa passeie pelo seu código incluindo chaves.Considero o primeiro claro, depois o segundo. Dá a sensação de instruções de fechamento, com pouco código é bom quando o código fica complexo
{...}
ajuda muito, mesmo que sejaendif
oubegin...end
fonte
É melhor definir o ponteiro como NULL quando terminar.
Aqui está um exemplo do porquê:
A classe A faz o seguinte:
A classe B faz o seguinte
Nesse ponto, tanto a Classe A quanto a Classe B têm ponteiros apontando para o mesmo bloco de memória. No que diz respeito à Classe A, esse bloco de memória não existe porque foi finalizado.
Considere o seguinte problema:
E se houvesse um erro lógico na Classe A que resultasse na gravação na memória que agora pertence à Classe B?
Nesse caso específico, você não receberá um erro de exceção de acesso incorreto porque o endereço de memória é legal, enquanto a classe A está corrompendo efetivamente os dados da classe B.
A classe B pode eventualmente travar se encontrar valores inesperados e, quando travar, as chances são de que você passará muito tempo caçando esse bug na classe B quando o problema estiver na classe A.
Se você tivesse definido o ponteiro de memória excluído como NULL, teria recebido um erro de exceção assim que qualquer erro lógico da Classe A tentasse gravar no ponteiro NULL.
Se você estiver preocupado com o erro lógico com exclusão dupla quando os ponteiros forem NULL pela segunda vez, adicione assert para isso.
Além disso: Se você estiver indo para votar, por favor, explique.
fonte
Ter sempre chaves é uma regra muito simples e robusta. No entanto, o código pode parecer deselegante quando há muitas chaves. Se as regras permitirem omitir chaves, deve haver regras de estilo mais detalhadas e ferramentas mais sofisticadas. Caso contrário, pode resultar facilmente em código caótico e confuso (não elegante). Portanto, procurar regras de estilo único separadas do restante dos guias e ferramentas de estilo usadas provavelmente é infrutífero. Trarei apenas alguns detalhes importantes sobre essa regra nº 3 que nem foram mencionados em outras respostas.
O primeiro detalhe interessante é que a maioria dos defensores dessa regra concorda em violá-la no caso de
else
. Em outras palavras, eles não exigem na revisão esse código:Em vez disso, se o virem, podem até sugerir que seja escrito assim:
Isso é tecnicamente uma violação dessa regra, pois não há colchetes entre
else
eif
. Essa dualidade da regra aparece quando tentar aplicá-la automaticamente à base de código com uma ferramenta irracional. Na verdade, por que argumentar, basta deixar uma ferramenta aplicar estilo automaticamente.O segundo detalhe (que também costuma ser esquecido pelos defensores dessa regra) é que os erros que podem ocorrer nunca são apenas por causa de violações à regra # 3. Na verdade, esses quase sempre envolvem violações da regra 1 também (com a qual ninguém discute). Novamente do ponto de vista das ferramentas automáticas, não é difícil criar uma ferramenta que reclama imediatamente quando a regra 1 é violada e, portanto, a maioria dos erros pode ser detectada em tempo hábil.
O terceiro detalhe (que muitas vezes é esquecido pelos oponentes dessa regra) é a natureza confusa da declaração vazia que é representada por ponto e vírgula único. A maioria dos desenvolvedores com alguma experiência ficou confusa, mais cedo ou mais tarde, com o ponto e vírgula no lugar errado ou com a declaração vazia que foi escrita usando o ponto e vírgula único. Duas chaves em vez de ponto e vírgula são visualmente mais fáceis de detectar.
fonte
Eu tenho que admitir que nem sempre use
{}
para linha única, mas é uma boa prática.Digamos que você escreva um código sem colchetes parecido com este:
for (int i = 0; i <100; ++ i) for (int j = 0; j <100; ++ j) DoSingleStuff ();
E depois de algum tempo, você deseja adicionar
j
outras informações ao loop, basta fazer isso por alinhamento e esquecer de adicionar colchetes.A distribuição de memória é mais rápida. Vamos dizer que você tem um grande escopo e cria grandes matrizes dentro (sem
new
elas estão na pilha). Essas matrizes são removidas da memória logo após você sair do escopo. Mas é possível que você use essa matriz em um único local, que ficará na pilha por um tempo e será algum tipo de lixo. Como uma pilha possui tamanho limitado e muito pequeno, é possível exceder o tamanho da pilha. Portanto, em alguns casos, é melhor escrever{}
para evitar isso. OBSERVAÇÃO: não é para uma linha, mas para tais situações:if (...) {// SomeStuff ... {// não temos if, while, etc. // SomeOtherStuff} // SomeMoreStuff}
A terceira maneira de usá-lo é semelhante à segunda. Apenas não para tornar a pilha mais limpa, mas para abrir algumas funções. Se você usa
mutex
funções longas, geralmente é melhor bloquear e desbloquear imediatamente antes de acessar os dados e logo após terminar de ler / escrever isso. OBSERVAÇÃO desta maneira está sendo usado se você possuir um poucoclass
oustruct
comconstructor
edestructor
para bloquear a memória.O que é mais:
se (...) se (...) SomeStuff (); else SomeOtherStuff (); // vai para o segundo if, mas o alligment mostra que está no primeiro ...
No geral, não posso dizer, qual é a melhor maneira de sempre usar
{}
para uma única linha, mas não é nada ruim fazer isso.EDIÇÃO IMPORTANTE Se você escrever colchetes de código de compilação para uma única linha, não fará nada, mas se o seu código for interpretado, ele diminui a velocidade do código muito, muito levemente. Muito levemente.
fonte
Existem várias maneiras possíveis de escrever instruções de controle; certas combinações delas podem coexistir sem prejudicar a legibilidade, mas outras combinações causarão problemas. O estilo
coexistirá confortavelmente com algumas das outras maneiras de escrever declarações de controle, mas não tão bem com outras. Se instruções controladas por várias linhas forem escritas como:
será visualmente óbvio quais
if
instruções controlam uma única linha e quais controlam várias linhas. Se, no entanto,if
instruções de várias linhas forem escritas como:então a probabilidade de alguém tentar estender uma
if
construção de instrução única sem adicionar os aparelhos necessários pode ser muito maior.A instrução de declaração única na próxima linha
if
também pode ser problemática se a base de código fizer uso significativo do formulárioMinha preferência é que ter a declaração em sua própria linha geralmente melhore a legibilidade, exceto nos casos em que houver muitas
if
declarações com blocos de controle semelhantes, por exemplonesse caso, geralmente precederei e seguirei esses grupos de
if
instruções com uma linha em branco para separá-los visualmente de outro código. Ter uma série de instruções que começam comif
o mesmo recuo fornecerá uma indicação visual clara de que há algo incomum.fonte