O que é uma asserção?

Uma asserção é uma condição que se deve sempre verificar-se num determinado ponto do programa.

Asserções em C

#include <assert.h>

assert( int cond ); 
prog: some_file.c:16: some_func: Assertion ... failed.

Exemplo

#include <assert.h>

int main(void) {
    int x = 5, y = -3;
    assert( 1 + 1 == 2 ); // OK
    assert( x*y > 0 );    // Assertion failed
    printf("%d\n", x*y);  // não executa
}

Porquê usar asserções

Pré-condição

Exemplo

Fatorial

#include <assert.h>

int factorial(int n) {
   assert(n >= 0);   // pré-condição
   int r = 1;
   for(int i = 2; i<=n; i++)
      r = r*i;
   return r;
}

int main(void) {
  ...
}

Execução

$ gcc -o fact fact.c

$ ./fact
Introduza um inteiro positivo:10
Factorial 10 = 362880

$ ./fact
Introduza um inteiro positivo:-1
fact: fact.c:6: factorial: Assertion `n >= 0' failed.

Observação

Uso de pré-condições

Exprimir condições de entrada de uma função, e.g.:

int some_fun( char *ptr, int size )
{
    assert( size <= LIMIT );
    assert( ptr != NULL );
    ...
}   

Pós-condição

Exemplo: Procurar um carater

int procurar(char str[], char ch);

Asserção de pós-condições

int procurar(char str[], char ch)  {
  int i = 0;
  while (str[i] != ch) {
    if(str[i] == '\0') {
        i = -1;
        break; // não encontrou
    }
    i++;
  }
  assert(i == -1 || (i>=0 && i<strlen(str)));
  return i;
}

Como usar pós-condições

Invariante

Exemplo: eliminar repetidos

   int elimrep(int v[], int n);

Asserções de invariantes

int elimrep(int vec[], int n) {
   int k = 0;
   for(int i = 0; i < n; i++) {
      assert(0 <= k && k <= i);
      assert(0 <= i && i < n);
      int val = vec[i];
      if(!ocorre(vec, k, val)) {
         vec[k++] = val;
            // valor não repetido
      }
   }
   return k;
}

Uso de invariantes

Asserções e erros

Distinguir entre:

Erro de programação

uma situação que não deve ocorrer; por exemplo: usar um índice inválido ou dividir por zero.

Erro de execução

uma situação que pode ocorrer e que devemos tratar; por exemplo: um input incompleto do utilizador.

Asserções são um mecanismo para detetar o primeiro tipo de erros — não para tratar os segundos.