"Se (0 == valor) ..." não faz mais mal do que bem? [fechadas]

49

Essa é uma das coisas que mais odeio quando a vejo no código de outra pessoa. Eu sei o que isso significa e por que algumas pessoas fazem dessa maneira ("e se eu acidentalmente colocar '=' em vez disso?"). Para mim, é muito parecido com quando uma criança desce as escadas contando os passos em voz alta.

Enfim, aqui estão meus argumentos contra:

  • Isso interrompe o fluxo natural da leitura do código do programa. Nós, humanos, dizemos "se o valor é zero" e não "se o zero é valor".
  • Os compiladores modernos avisam quando você tem uma tarefa em sua condição ou, na verdade, se sua condição consiste apenas nessa tarefa, que, sim, parece suspeita de qualquer maneira
  • Você não deve esquecer de colocar double '=' quando estiver comparando valores se for um programador. Você também pode esquecer de colocar "!" ao testar a não igualdade.
mojuba
fonte
17
Também não me importo muito com isso, mas está bem abaixo da minha lista pessoal de irritações.
quer
7
E os programadores sentem falta do duplo '=' algumas vezes. É um erro fácil de cometer e que é muito fácil de ignorar.
sange
8
Como isso não é construtivo ou não é uma questão real?
TheLQ 5/11/10
7
Isso está fechado, então aqui está minha breve opinião: como as pessoas podem se lembrar de escrever, 0 == valuemas não se lembram de escrever ==? Quero dizer blimey, se você está pensando sobre isso, por que não escrever corretamente para começar.
dr Hannibal Lecter
3
@muntoo: Segundo os compiladores, muitas coisas estão "corretas", não acho que seja uma boa referência.
dr Hannibal Lecter

Respostas:

59

Ah, sim, "Condicionais Yoda" ("Se o valor for zero, execute este código, você deve!"). Eu sempre aponto quem afirma que é "melhor" em ferramentas como o lint (1). Esse problema específico foi resolvido desde o final dos anos 70. A maioria das linguagens modernas nem compila uma expressão como if(x = 10), pois se recusa a coagir o resultado da atribuição a um booleano.

Como outros já disseram, certamente não é um problema, mas provoca um pouco de dissonância cognitiva.

TMN
fonte
32
+1 para "condicionais Yoda". Eu realmente ri disso. :)
Bobby Tables
3
Enquanto a ordem é boa, eu me oponho à comparação com zero, em vez da conversão booleana simples if(!value),.
SF.
11
Então, você considera atribuições dentro de um erro condicional?
4
"A maioria dos idiomas modernos nem compila isso" O problema surge quando você está usando um idioma que coagia silenciosamente o resultado da atribuição a um booleano. A linguagem mais popular em que consigo pensar seria JavaScript. É por isso que eu sempre uso condicionais yoda, mesmo em Java, para não esquecer quando estou escrevendo javascript. Alterno entre os dois com frequência suficiente para que possa (e tenha) sido um problema.
Sam Hasler
3
Alguém sabe de um compilador que não será compilado if (0 == x)?
91318 Kristopher Ives
56

É desagradável porque impõe uma taxa mental pequena, mas perceptível.

As pessoas leem da esquerda para a direita em praticamente todas as linguagens de programação (e na maioria das linguagens naturais).

Se eu vejo 123 == x, a maneira como analiso é:

  • 123- E daí? informação incompleta.
  • == - bem, 123 é 123, por que testá-lo ...
  • x- ok, então é com isso que estamos preocupados. Só agora eu tenho o contexto.
  • Volte a reconsiderar 123e por que x é comparado a ele.

Quando vejo x == 123a análise mental é:

  • x- Fornece contexto, eu sei do que se trata a condição. Eu posso optar por ignorar o resto. Com base no fluxo anterior, tenho uma boa idéia do porquê e do que está por vir (e se surpreenda se for diferente).
  • == - Eu pensei assim.
  • 123 - Sim.

A interrupção é pequena (em um exemplo simples), mas eu sempre percebo.

Colocar o valor em primeiro lugar pode ser uma boa ideia, se você quiser chamar a atenção, por exemplo if (LAUNCH_NUKES == cmd). Normalmente, essa não é a intenção.

dbkk
fonte
5
Exatamente. Nas línguas naturais a constante sempre vem por último, pela mesma razão: se a luz é vermelha ...
mojubá
2
@mojuba É verdade, é quase universal. Estranhamente, existem algumas linguagens naturais em que o objeto vem antes do assunto (ordem OVS / OSV), mas são todas obscuras.
dbkk
11
Por outro lado, alguns de nós tendem a ler os símbolos antes da variável. Eles são mais atraentes. Então, eu vou analisar fora =ou ==antes 123ou x, e acabam por não se preocupar em traduzir o código para Inglês na minha cabeça.
Izkata 9/07/12
Além disso, a maioria dos compiladores avisará se solicitado corretamente, a menos que alguém use chaves extras, por isso tenta resolver um não-problema.
Deduplicator
47

Prejudicial? Não. Funciona de qualquer maneira.

Má prática? Discutível, na melhor das hipóteses. É uma simples programação defensiva.

Vale a pena perder o sono? Nah.

Wonko, o são
fonte
8
E quando o leio, entendo imediatamente o código, que é para mim o motivo mais importante para debater um estilo de codificação. Eu concordo totalmente, não vale a pena perder o sono.
Jeff Siver
17

Isso é basicamente flaimbait.

Não, não faz mais mal do que bem. Simples.

Mais palavras?

Argumento do compilador? Erm, ish, talvez - não confie demais no complier para salvá-lo de si mesmo.

"Você não deve esquecer" - bem, duh - não, é claro que não deveria. Enquanto isso, eu estou cansada, eu tenho codificado o dia todo, tive que usar duas línguas diferentes e, às vezes, apenas às vezes, ser humano que eu faço um erro.

O objetivo desse tipo de comportamento é que é defensivo, não existe porque você espera cometer erros mais do que você tem seguro porque espera falhar ... mas se você faz o melhor para ser coberto.

Difícil de ler? Você está reclamando que um programador decente deve ter == hardwired (o que faz todo tipo de suposições ruins), mas que o mesmo programador decente não pode ler o valor 0 == ??

Não faz mal, tem benefícios em potencial, pergunta boba, deixa os outros fazerem se quiserem e seguir em frente.

Murph
fonte
6
Eu acho que 0 == valor não é natural para quem estudou álgebra muito antes de estudar programação.
Mjuba
4
Esse não é o ponto - sim, você está certo, não lê direito, mas igualmente grande parte do que nós, como programadores, escrevemos, não se comporta exatamente como linguagem natural e é uma questão de como você interpreta o que você vê
Murph
4
Bravo .. Sem mencionar o fato de que, devido à sua leitura não natural, você está inclinado a prestar mais atenção a ela, capturando possíveis erros.
Mocj
7
@mocj - Portanto, todos devemos codificar da maneira mais obtusa possível para garantir que as pessoas que leem nosso código precisem realmente ler nosso código?
Kaz Dragon
6
@mocj - Eu aprecio isso, mas seu argumento foi que o "cérebro gaguejar" enquanto você lê o condicional Yoda é uma coisa boa. Estou fazendo a pergunta de que, se for esse o caso, devemos procurar escrever todo o código para causar "gagueiras no cérebro"? Pergunta genuína.
Kaz Dragon
11

Eu não chamaria isso de mal, mas é desagradável. Então não, eu não diria que sim.

whatsisname
fonte
10

Eu nunca senti que o todo 'e se eu esquecer um =?' realmente realmente teve muito peso. Sim, você pode cometer erros de digitação, mas todos cometemos erros de digitação, parece tolice mudar todo o seu estilo de codificação, porque você tem medo de cometer um erro. Por que não tornar todas as suas variáveis ​​e funções todas minúsculas sem pontuação, porque você pode esquecer de colocar algo em maiúscula ou esquecer um sublinhado um dia?

GSto
fonte
5
Esse não é o ponto da questão, o ponto é "é prejudicial" - e não é. Uma irritação muito menor, na pior das hipóteses, mas não prejudicial.
Murph
11
Em linguagens dinâmicas - absolutamente, você pode digitar errado um símbolo e depois perder seu tempo procurando a fonte do seu bug
mojuba
3
com todo o respeito, quando você passa uma madrugada (ou duas) e encontra a fonte (no código C ++) é = = em vez de ==, isso levaria algum peso.
DevSolo #
2
@DevSolo: Eu acho que realmente deve acontecer uma ou duas vezes em sua carreira, mas não mais do que isso
mojubá
9

Algumas pessoas o usam para deixar claro exatamente o que um condicional está fazendo. Por exemplo:

Caminho 1:

FILE *fp;

fp = fopen("foo.txt", "w+");
if (fp == NULL) {

Caminho 2:

FILE *fp;

if (NULL == (fp = fopen("foo.txt", "w+"))) {

Algumas pessoas acham que o segundo exemplo é mais conciso ou os argumentos de reversão ilustram o ponto de um teste (condicional) antes do próprio teste.

Na verdade, eu realmente não me importo de nenhuma maneira. Eu tenho minhas preocupações sobre estilo e a maior delas é a inconsistência. Portanto, faça da mesma maneira, de forma consistente, e não me importarei de ler seu código.

Misture até o ponto em que parece que seis pessoas diferentes, com seu próprio estilo distinto, trabalharam ao mesmo tempo, fico um pouco irritado.

Tim Post
fonte
4
O segundo exemplo me fez ir "hein?" O primeiro é muito mais legível. Ótimo exemplo. :)
Mateen Ulhaq
6

Para mim, é um condicionamento simples. Como alguém que aprendeu (nos anos 90) C e C ++, me acostumei a ele e ainda o uso, mesmo que as razões sejam lidas.

Quando você está "condicionado" a procurar a "constante" no lado esquerdo, ela se torna uma segunda natureza.

Eu também o uso apenas para equivalência (ou equivalência negada), não para maior / menor que.

Concordo plenamente com a resposta de @ Wonko.

DevSolo
fonte
5

O único caso em que acho útil é que a parte variável do if é bastante longa e ver os valores facilita a leitura do código. As linguagens de namespace pontilhadas têm os melhores exemplos disso.

Por exemplo, algo em que trabalhei com o logon único teve uma situação em que você poderia ter duas sessões simultâneas se um certo tipo de erro ocorreu e foi recuperado de uma certa maneira, então eu tenho que adicionar um manipulador para o que estava dentro de um que parecia algo assim:

if (2 <= application.httpcontext.current.session["thenameofmysessiontoken"].items.count())

É certo que neste exemplo existem outras maneiras de fazer isso, mas esse seria um caso em que a versão número primeiro é potencialmente mais legível.

Conta
fonte
2
Eu acho que a palavra-chave aqui é "outras maneiras de fazer isso";)
mojubá
nesse caso, sim, mas em alguns casos esse ainda é o resultado mais legível. Meu único ponto é que existem algumas razões legítimas para fazer isso a não ser para a linguagem de combate ou comportamento ide e tipo o-
Bill
Para ser sincero, tenho dificuldades com as condições Yoda para <= e> =. O sinal == é uma questão diferente, porque na minha cabeça eu posso mudar os símbolos, mas no seu caso eu preciso lembrar que count () tem que ser maior ou igual a 2, e isso é bastante irritante derivar de um sinal menor ou igual.
Alex
3

E, no entanto, os erros ocorrem. E, às vezes, você deseja uma atribuição em um operador de loop em que possa verificar a igualdade ou, pelo menos, é uma prática padrão usá-la.

Eu o mantenho um pouco. O conselho que segui (possivelmente do Code Complete) é manter o valor mais baixo à esquerda nas comparações. Eu estava discutindo isso com um colega mais cedo e ele pensou que era meio louco, mas eu me acostumei muito.

Então eu diria:

if ( 0 <= value )

Mas eu também diria:

if ( value <= 100 )

Igualdade, tenderei a verificar com a variável à esquerda, é apenas mais legível.

glenatron
fonte
11
Estou acostumado a usar if(y > x)o tempo todo. A menos que yseja uma constante.
Mateen Ulhaq 5/11/10
Eu costumava fazer dessa maneira, mas depois que tive a ideia de ter os valores mais baixos à esquerda, descobri que meu código é muito mais legível à primeira vista.
glenatron