Armadilhas com a falta de parênteses

Toda expressão lógica que possui algum dos operadores lógicos and, or, xor, entre outros, precisa agrupar cada comparação com parênteses para que o compilador entenda como a expressão deve ser interpretada.

Isto é necessário porque os operadores lógicos or, and e xor podem ser aplicados tanto para valores lógico (False or True é igual a True) como em aritmética binária (3 or 5 é igual a 7).

Na expressão:

  if a = 1 or b = 2 then

o compilador irá interpretar:

  if (a = (1 or b)) = 2 then

porque o or tem precedência maior do que o sinal de igual, e ocorrerá um erro de compilação porque, embora a comparação 1 or b seja válida (aritmética binária) e seu resultado possa ser comparado com a (um número), esta expressão não pode ser comparada com 2 porque 2 não é um valor lógico (Boolean).

Boa parte da falta de uso dos parênteses é pego em tempo de compilação, porque geralmente sua falta irá resultar em um código que o compilador não pode interpretar. Mas isto nem sempre é verdadeiro.

Outro dia o código abaixo me pregou uma peça:

  Result := HasInstance and FInstance.Documents.Count > 0;

HasInstance é uma função, retorna um Boolean e eu a utilizo para assegurar que FInstance, um Variant, aponta para um objeto OLE (de ligação tardia) válido. Durante os testes do sistema eu recebi uma mensagem de erro informando que o tal FInstance não apontava para um objeto OLE válido. Ao debugar o código, vi que o erro saltava da linha acima.

Minha primeira reação foi verificar se a opção Complete Boolean Evaluation estava desligada (estava), depois se HasInstance estava verificando o conteúdo de FInstance corretamente, e também estava (o resultado era False). Depois é que percebi a falta dos parênteses: o compilador gerou código de forma que o conteúdo de HasInstance e FInstance.Documents.Count fosse tratado pelo and, e somente depois fosse comparado com 0. O fato de FInstance ser um Variant, não gerando erro de compilação por tipos incompatíveis, fez com que o problema fosse apresentado apenas em tempo de execução.

Portanto muito cuidado com a falta de parênteses. Melhor pecar pelo excesso de zelo do que pela falta dele, sem falar que o uso dos parênteses deixa a expressão mais legível.

One thought on “Armadilhas com a falta de parênteses”

  1. Olá João,

    Concordo plenamente com “…Melhor pecar pelo excesso de zelo do que pela falta dele”.

    Então o código ficaria assim:

    Result := HasInstance and (FInstance.Documents.Count > 0);

    Um abraço!

Comments are closed.