Download Capítulo 3

Transcript
3.2. FUNÇÕES E PROCEDIMENTOS: ROTINAS
109
reduzFracção(n, d);
// Escrita do resultado:
cout < < "A soma de ";
escreveFracção(n1, d1);
cout < < " com ";
escreveFracção(n2, d2);
cout < < " é ";
escreveFracção(n, d);
cout < < ’.’ < < endl;
}
}
Neste caso é evidente que não haverá violação de nenhuma pré-condição. Muitos terão a
tentação de perguntar para que servem as asserções neste momento, e se não seria apropriado
eliminá-las. Há várias razões para as asserções continuarem a ser indispensáveis:
1. O programador, enquanto produtor, não deve assumir nada acerca dos consumidores
(muito embora em muitos casos produtor e consumidor sejam uma e a mesma pessoa).
O melhor é mesmo colocar a asserção: o diabo tece-as.
2. O produtor deve escrever uma rotina pensando em possíveis reutilizações futuras. Pode
haver erros nas futuras utilizações, pelo que o mais seguro é mesmo manter a asserção.
3. Se alguém fizer alterações no programa pode introduzir erros. A asserção nesse caso
permitirá a sua rápida detecção e correcção.
Parece ter faltado algo em toda esta discussão: a condição objectivo. Tal como se deve usar asserções para verificar as pré-condições, também se deve usar asserções para verificar as condições objectivo. A falsidade de uma condição objectivo, sabendo que a respectiva pré-condição
é verdadeira, é também devida a um erro de programação, só que desta vez o responsável pelo
erro é o programador produtor. Assim, as asserções usadas para verificar as pré-condições servem para o produtor de uma rotina facilitar a detecção de erros do programador consumidor,
enquanto as asserções usadas para verificar as condições objectivo servem para o produtor de
uma rotina se proteger dos seus próprios erros.
Transformar as condições objectivo em asserções é, em geral, uma tarefa mais difícil que no
caso das pré-condições, que tendem a ser mais simples. As maiores dificuldades surgem especialmente se a condição objectivo contiver quantificadores (somatórios, produtos, quaisquer
que seja, existe uns, etc.), se estiverem envolvidas inserções ou extracções de canais (entradas
e saídas) ou se a condição objectivo fizer menção aos valores originais das variáveis, i.e., ao
valor que as variáveis possuiam no início da rotina em causa.
Considere-se cada uma das rotinas do programa.
O caso da função mínimo() é fácil de resolver, pois a condição objectivo traduz-se facilmente
para C++. É necessário, no entanto, abandonar os retornos imediatos e guardar o valor a