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