Minha pergunta é sobre a linha que mencionei no assunto e que posso ver em muitos lugares dentro do código de produção.
O código geral fica assim:
if (0) {
// Empty braces
} else if (some_fn_call()) {
// actual code
} else if (some_other_fn_call()) {
// another actual code
...
} else {
// default case
}
Os outros ramos são irrelevantes para a minha pergunta. Gostaria de saber qual é o significado de colocar if (0)
aqui. As chaves estão vazias, então não acho que deva comentar algum bloco de código. Isso força o compilador a fazer alguma otimização ou suas intenções são diferentes?
Eu tentei procurar esse caso explícito aqui no SO e na internet, mas sem sucesso. Há perguntas semelhantes sobre JavaScript, mas não C. Há outra pergunta: o que acontece quando um zero é atribuído em uma condição `if`? , mas discute a atribuição zero a uma variável, não o uso 'if (0)' em si.
c
if-statement
Zzaponka
fonte
fonte
Respostas:
Às vezes, uso isso como simetria para poder mover o outro
else if{
livremente com o meu editor sem ter que me preocupar com o primeiroif
.Semanticamente o
parte não faz nada e você pode contar com otimizadores para excluí-lo.
fonte
if else
prefixo comum a todos os caminhos de código significativos alinha bem as condições e facilita a verificação. (Isso é subjetivo, embora, e vai depender muito do que é realmente dentro das condições e blocos de código.)if (0) {..}
apresenta nenhum problema de parsabilidade / legibilidade. Deveria ser óbvio para quem conhece um pouco de C. Isso não é problema. O problema é a pergunta seguinte após a leitura: "Para que diabos é então?" A menos que seja para fins de depuração / temporários (ou seja, a intenção é "ativar" esseif
bloco posteriormente)), eu recomendaria a remoção por completo. Basicamente, "ler" esse código provavelmente causaria uma "pausa" desnecessária para o leitor, sem uma boa razão. E esse é um motivo suficientemente bom para removê-lo.else if
pelo editor sem se preocupar" porque as condições podem não ser mutuamente exclusivas; nesse caso, a ordem é importante. Pessoalmente, eu usaria apenasif
e executaria o retorno antecipado , extraindo a cadeia lógica para uma função separada, se necessário.Isso pode ser útil se houver
#if
instruções, alaetc.
Nesse caso, todos (e todos) os testes podem ser
#if
executados e o código será compilado corretamente. Quase todos os compiladores removerão aif (0) {}
peça. Um gerador automático simples pode gerar código como este, pois é um pouco mais fácil de codificar - ele não precisa considerar o primeiro bloco ativado separadamente.fonte
if
/else if
não é usada tanto como uma árvore de decisão, mas como uma construção "agir na primeira condição de correspondência", onde a condição que tem a maior prioridade não é particularmente "especial". Embora eu não tenha visto issoif(0)
como uma maneira de permitir que todas as ramificações reais tenham sintaxe consistente, eu gosto da sintaxe consistente que ela facilita.else if
linha em duas e colocar a proteção do pré-processador no meio.if (0)
galho e reformatava o restante, de modo que estivesseelse
em sua própria linha, cercado por um guarda ao longo das linhas de#if TEST1_ENABLED && TEST2_ENABLED
.Eu vi um padrão semelhante usado no código gerado. Por exemplo, no SQL, vi bibliotecas emitirem a seguinte
where
cláusula.Presumivelmente, isso facilita a adição de outros critérios, porque todos os critérios adicionais podem ser anexados com
and
uma verificação adicional para verificar se esse é o primeiro critério ou não.fonte
1=1
também é "útil" porque você sempre pode adicionar owhere
na frente, incondicionalmente. Caso contrário, você teria que verificar se está vazio e, em caso afirmativo, evite gerar awhere
cláusula.1=1
doWHERE
, para que não tenha impacto no desempenho.Como está escrito, a
if (0) {}
cláusula não compila em nada.Suspeito que a função da cláusula no topo dessa escada seja fornecer um local fácil para desativar temporariamente todas as outras funcionalidades de uma só vez (para fins de depuração ou comparação), alterando
0
para a1
outrue
.fonte
Não tenho certeza de nenhuma otimização, mas meus dois centavos:
Isso aconteceu devido a alguma modificação de código, onde uma condição primária foi removida (a chamada de função no
if
bloco inicial , digamos), mas os desenvolvedores / mantenedoresif-else
blocoentão, em vez de remover o
if
bloco associado , eles simplesmente alteraram a condiçãoif(0)
e seguiram em frente.fonte
if(0)
Também não diminui a cobertura das agências?É código podre.
Em algum momento em que "se" fez algo útil, a situação mudou, talvez a variável que está sendo avaliada tenha sido removida.
A pessoa que estava consertando / alterando o sistema fez o mínimo possível para afetar a lógica do sistema, para garantir que o código fosse recompilado. Então ele deixa um "se (0)" porque é rápido e fácil e não tem muita certeza de que é isso que ele quer fazer. Ele faz o sistema funcionar e não volta para corrigi-lo completamente.
Em seguida, o próximo desenvolvedor aparece e pensa que foi feito deliberadamente e apenas comenta essa parte do código (já que não está sendo avaliado de qualquer maneira), e na próxima vez em que o código for tocado, esses comentários serão removidos.
fonte
Uma possibilidade ainda não mencionada: a
if (0) {
linha poderia estar fornecendo um local conveniente para um ponto de interrupção.A depuração geralmente é feita em código não otimizado, portanto o teste sempre falso estará presente e poderá ter um ponto de interrupção definido. Quando compilada para produção, a linha de código seria otimizada. A linha aparentemente inútil fornece funcionalidade para desenvolvimento e teste de compilações sem impactar as versões.
Existem outras boas sugestões acima também; a única maneira de realmente saber qual é o objetivo é localizar o autor e perguntar. Seu sistema de controle de código-fonte pode ajudar com isso. (Procure a
blame
funcionalidade do tipo.)fonte
Vi blocos de código não alcançáveis no JavaScript pré-expandido que foram gerados usando uma linguagem de modelo.
Por exemplo, o código que você está lendo pode ter sido colado de um servidor que pré-avaliou a primeira condição que naquele momento contava com uma variável disponível apenas no lado do servidor.
que uma vez pré-compilado tem:
espero que isso ajude a relativizar a atividade potencial de baixo teclado da era dos codificadores pró-reciclagem, pela qual eu demonstro entusiasmo!
fonte
Essa construção também pode ser usada em C para implementar programação genérica com segurança de tipo, baseando-se no fato de que o código inacessível ainda é verificado pelo compilador:
fonte
Eu acho que é apenas um código ruim. Escrevendo um exemplo rápido no Compiler Explorer, vemos que no gcc e no clang nenhum código é gerado para o
if (0)
bloco, mesmo com as otimizações completamente desabilitadas:https://godbolt.org/z/PETIks
Brincando com a remoção das
if (0)
causas, não há alterações no código gerado, então concluo que isso não é uma otimização.É possível que houvesse algo no
if
bloco superior que foi removido mais tarde. Em resumo, parece que removê-lo causaria a geração exata do mesmo código, portanto, fique à vontade para fazer isso.fonte
Como foi dito, o zero é avaliado como falso, e o ramo provavelmente será otimizado pelo compilador.
Eu já vi isso antes no código em que um novo recurso foi adicionado e um interruptor de interrupção era necessário (se algo der errado com o recurso, você pode simplesmente desativá-lo) e algum tempo depois, quando o interruptor de interrupção foi removido O programador também não removeu o ramo, por exemplo
passou a ser
fonte
Isso ajuda a depurar esse bloco apenas colocando o bloco 1. Se isso desabilitar a funcionalidade de bloco all if else. E também podemos expandir o bloco if else.
fonte
fonte
A resposta de @ PSkocik é boa, mas adiciono meus dois centavos. Não tenho certeza se devo fazer isso como um comentário ou como resposta; escolhendo o último, porque IMHO vale a pena ver outros, enquanto comentários são frequentemente invisíveis.
Não só uso ocasionalmente
Mas eu também ocasionalmente
ou
para condições complicadas. Pelas mesmas razões - mais fácil de editar, #ifdef, etc.
Por falar nisso, no Perl eu farei
Eu comparo o
if(0)
código ao lispque você adivinhou, posso recuar como
Às vezes, tentei imaginar como seria uma sintaxe legível por humanos.
Possivelmente
inspirado pelo de Dikstra [ https://en.wikipedia.org/wiki/Guarded_Command_Language#Selection:_if][Guarded Command Language].
Mas essa sintaxe implica que as condições são avaliadas em paralelo, enquanto
if...else-if
implica avaliação sequencial e priorizada das condições.Comecei a fazer esse tipo de coisa ao escrever programas que geravam outros programas, onde é especialmente conveniente.
Enquanto estamos trabalhando nisso, ao escrever RTL usando o antigo iHDL da Intel, codifiquei coisas como
onde
FORC..DOC..ENDC
é uma construção de loop de pré-processador de macro, que se expande paraEsse era um código de atribuição única, não imperativa, portanto, a configuração de uma variável de estado não era permitida, se você precisasse fazer coisas como encontrar o primeiro bit definido.
Venha para pensar sobre isso, este pode ter sido o primeiro lugar que eu encontrei essas construções.
BTW, as objeções que alguns tinham ao estilo if (0) - de que as condições else-if-dependem sequencialmente e não podem ser reordenadas arbitrariamente - não se aplicam à lógica AND e OR e XOR na RTL - mas se aplicam a circuito && e ||.
fonte
Eu já vi isso usado para lidar com erros, por exemplo
Isso pode ser útil quando goto é usado para gerenciar erros, as instruções são executadas apenas quando ocorre um erro. Eu vi isso no código C muito antigo (onde argumentos de função são escritos fora do '()'), não pense que alguém segue isso agora.
fonte
Eu já vi isso algumas vezes, acho que a razão mais provável é que ele estava avaliando algo em uma versão / ramificação do código mais antiga / diferente ou possivelmente para depuração, e alterá-lo para
if(0)
é uma maneira um tanto preguiçosa de remover o que estava lá .fonte