É certo que um condicional tenha efeitos colaterais? [fechadas]


10

Estou fazendo um curso intermediário de estruturas de dados como pré-requisito para ingressar no programa CS MS em uma universidade da qual todos os EUA já ouviram falar. Uma linha de código escrita em classe chamou minha atenção:

if (a > 33 | b++ < 54) {...}

Isso não passaria em uma revisão de código no meu local de trabalho. Se você escreveu um código como esse em uma entrevista, isso seria um golpe significativo contra você. (Além de ser condicional com efeitos colaterais, é inteligente às custas da clareza.)

Na verdade, nunca vi um condicional com efeitos colaterais, e o Google também não aparece muito. Outro aluno ficou para trás depois da aula para perguntar sobre isso também, então não sou o único que achou isso estranho. Mas o professor foi bastante inflexível quanto ao fato de ser um código aceitável e que ele escreveria algo assim no trabalho. (O trabalho dele no FT é como SWE principal em uma empresa que você já ouviu falar.)

Não consigo imaginar um mundo em que essa linha de código seja aceitável, muito menos desejável. Estou errado? Isso está bom? E o caso mais geral: condicionais com efeitos colaterais? Eles estão sempre bem?


7
Essa linha deve ser retirada da órbita. Duas vezes por uma boa medida.
Blrfl

8
Um ponto: um único tubo (barra vertical) é um bit a bit - ou na maioria dos idiomas, em vez de um "ou" lógico. Não provoca curto-circuito se o lado esquerdo for verdadeiro. Como esse condicional tem efeitos colaterais no lado direito, faz uma diferença especialmente grande no resultado.
Jonathan Eunice

2
Existem idiomas usados ​​em vários idiomas que se enquadram nessa categoria, mas por serem "bem conhecidos" ou "normais" não causam problemas. A linha da pergunta não parece se encaixar na categoria de uso idiomático, então eu a evitaria.
Jaydee

2
@ JonathanEunice, sim, algumas pessoas ficaram confusas sobre a avaliação de curto-circuito. Não é um erro de digitação da minha parte.
rianjs

5
Olhe para o lado positivo. Agora você conhece mais uma empresa na qual não deseja entrevistar.
John R. Strohm

Respostas:


23

um efeito colateral semicondicional em que posso pensar:while(iter.MoveNext())

Dito isto, acho que isso se encaixa principalmente na categoria " nunca é um grande qualificado". Eu posso pensar em alguns casos raros em que eu já vi isso aceitável, mas em geral isso é vil e deve ser evitado.

Também não consigo pensar em um cenário em que essa linha em particular seria aceitável, mas também não consigo pensar em um cenário em que essa linha em particular seria útil , por isso é difícil imaginar o contexto em que está.


Era apenas uma linha descartável em um método durante a aula. Não era para fazer nada de útil.
rianjs

4
De maneira equivalente, as while(v = *p++)varreduras no estilo C / C ++ através de uma matriz terminada em zero (por exemplo, string C) são bastante comuns e amplamente aceitas.
Phil Miller

3
Eu sempre considerei condicionais de loop do formulário while(c = input.read() != '\n')razoavelmente idiomáticas.

1
Pode haver algumas expressões comuns aceitáveis, mas claramente "ser inteligente à custa da clareza" cai no campo NUNCA.
Julia Hayward

Eu esqueci completamente iter.MoveNext (). Um caso completamente razoável para uma condição ter um efeito colateral. Obrigado!
rianjs

8

No meu mundo, uma leitura da memória pode ser considerada um efeito colateral (por exemplo, E / S mapeada na memória).

Agora, considere o seguinte:

    while( ( *memory_mapped_device_status_register & READY_FLAG) == 0) {
       // Wait
    }

E compare com:

    status = *memory_mapped_device_status_register;
    while( ( status & READY_FLAG) == 0) {
        // Wait
        status = *memory_mapped_device_status_register;
    }

Evitar o efeito colateral (a leitura) na condição ajudou na legibilidade; ou apenas duplicou o código e adicionou confusão?

Não é aceitável que uma condição tenha efeitos colaterais (se isso torna o código menos legível) e também não é aceitável que uma condição tenha efeitos colaterais (se isso torna o código mais legível). O fator chave é "legibilidade". Tudo o resto são regras criadas por tolos em uma tentativa equivocada de melhorar a legibilidade (embora muitas vezes tenham o efeito oposto).


3

Como sempre com essas perguntas, isso é uma questão de grau. Se houvesse prova inequívoca de que qualquer efeito colateral em uma ifexpressão sempre levasse a um código pior, não seria legal criar essas expressões. Projetistas da linguagem pode ser ideosyncratic, os seres humanos falíveis, mas eles não são que estúpido.

Dito isto, quais são exemplos de efeitos colaterais justificados dentro de um if? Por exemplo, suponha que você seja legalmente obrigado a registrar todo e qualquer acesso à propriedade Pde uma entidade Epara fins de auditoria. (Imagine que você está trabalhando em uma planta de enriquecimento de urânio e há controles legais muito rígidos sobre o que seu código pode fazer e como deve fazê-lo.) Então qualquer um ifque verifique essa propriedade causará o efeito colateral do log de auditoria sendo estendido.

Essa é uma preocupação transversal bastante clara, não afeta muito o seu raciocínio sobre o estado do programa, e você pode implementá-lo para que fique completamente invisível e não distraia quando você revisa a linha com o if(oculto). afastado no acessador, ou ainda melhor via AOP). Eu diria que é um caso bastante claro de um efeito colateral que não é uma preocupação. Situações semelhantes podem ser imaginadas quando você apenas deseja contar execuções de ramificações para fins de criação de perfil, etc.

Quanto mais essas circunstâncias atenuantes desaparecerem, mais estranho o construto se tornará. Se um tipo de loop específico (por exemplo, if((c = getc()) == 'x') { quit(); }é bem conhecido e aceito pela comunidade de idiomas, é muito menos problemático do que quando você o inventa espontaneamente, etc. Sua linha de exemplo fica aquém desse padrão, mas eu poderia imaginar muito, muito mais horríveis que eu nem vou digitar, são tão horríveis.


2

Embora o código seja realmente fedorento, ele tem a vantagem de ser mais simples (e talvez mais rápido se você não tiver um bom compilador de otimização) do que o equivalente if (a > 33 | b < 54) {b++; ...} else b++;

mas é claro que é possível otimizá-lo da seguinte forma (mas cuidado! este possui um comportamento diferente em caso de estouro!): b++; if (a > 33 | b < 53) {...}

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.