Cuidado com o operador?: E coloque-o entre parênteses

Este bug foi encontrado no código-fonte do Haiku.

Código incorreto:

bool IsVisible(bool ancestorsVisible) const
{
int16 showLevel
= BView::Private(view).ShowLevel();
return (showLevel - (ancestorsVisible) ? 0 : 1) <= 0;
}

Explicação:

O operador ternário?: Tem uma precedência muito baixa, menor do que as operações /, +, <, etc.

Também é inferior à precedência do operador ‘-‘. Esquecer isso pode resultar em um comportamento inesperado do programa.

O programador pensa que as operações serão executadas na seguinte ordem:

(showLevel - (ancestorsVisible ? 0 : 1) ) <= 0

Mas a sequência será realmente esta:

((showLevel - ancestorsVisible) ? 0 : 1) <= 0

O código não é muito complicado, certo? O fato de o programador cometer um erro em um código tão simples e curto só prova o quão perigoso o operador?: Pode ser. É muito fácil errar ao usá-lo. E usar o operador ternário em condições mais complexas deve ser tratado como pura sabotagem. Não é apenas a probabilidade de você cometer e perder um erro, mas também o fato de essas expressões serem muito difíceis de ler.

Código correto:

return showLevel - (ancestorsVisible ? 0 : 1) <= 0;

Recomendação:

Em meus artigos anteriores, eu recomendaria usar o operador ternário apenas em expressões simples. Mas, como prova o exemplo acima, os programadores tendem a cometer erros em expressões curtas e simples também.

Eu não sugiro rejeitar o operador?: Completamente. Pode ser útil e até necessário às vezes.

Portanto, prefiro recomendar fazer o seguinte.

SEMPRE coloque o operador ternário entre parênteses.

Suponha que você tenha uma expressão:

A = B ? 10 : 20;

Então você deve escrever assim:

A = (B ? 10 : 20);

Sim, os parênteses são excessivos aqui.

Mas protegerá seu código mais tarde, quando você ou seu colega adicionar uma variável X a 10 ou 20 ao fazer a refatoração de código:

A = X + (B ? 10 : 20);

Sem os parênteses, você poderia esquecer que o operador?: Tem uma precedência baixa e acidentalmente interrompe o programa.

Inscreva-se para receber novas dicas em: http://eepurl.com/bvZrnf
ou leia-as em http://cpphints.com