Published by Joao Morais on 17 Nov 2007 at 09:47 pm
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 Response to “Armadilhas com a falta de parênteses”
Leave a Reply
You must be logged in to post a comment.
Silvio Clécio on 21 Oct 2008 at 10:30 pm #
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!