Olá, caro leitor! Continuando o assunto sobre o pré-processador C, vamos discutir neste artigo alguns recursos utilizados para realizar diagnóstico durante o processo de compilação e execução de um programa. Vamos lá!
Macros Predefinidas para Diagnóstico
O padrão C ANSI possui algumas macro predefinidas que podem ser utilizadas na codificação. Cabe ressaltar que o próprio compilador pode definir algumas macros. As macros predefinidas são:
__LINE__
É um número inteiro que representa a linha atual do arquivo que está sendo compilado.
__FILE__
É uma string que representa o nome do arquivo que está sendo compilado.
__DATE__
É uma string que representa a data (formato “Mmm dd yyyy”) em que o arquivo foi compilado.
__TIME__
É uma string que representa o horário (formato “hh:mm:ss”) em que o arquivo foi compilado.
__STDC__
É um número inteiro que indica se o compilador segue o padrão C ANSI. Se o valor é igual à constante decimal 1 então o compilador segue o padrão C ANSI, caso contrário o compilador segue outro padrão.
Controle de linha
A diretiva #line é utilizada para indicar ao pré-processador qual o número da linha que está sendo processada. Essa diretiva pode ser utilizada para prover uma informação mais detalhada do processo de compilação/depuração, oferecendo diagnóstico durante essa fase.
Quando essa diretiva é utilizada, o conteúdo das macros __LINE__ e __FILE__ são alteradas conforme o contexto. Essa diretiva pode ser utilizada de duas maneiras, sendo sua forma geral:
#line <num> <”arquivo”>
O nome do arquivo é um parâmetro opcional. Considere, por exemplo, o código abaixo:
#line 300
void Test(void * ptrData) //300
{ //301
if(ptrData == NULL) //302
{ //303
printf("[%s - linha: %i]Ponteiro NULL!", __FILE__, __LINE__);//304
}
/*.....*/
}
A declaração de
#line 300
determina que a contagem de linha é iniciada com o valor 300. No exemplo as macros __FILE__ e __LINE__ são utilizadas para formatar uma mensagem com detalhes da linha e do arquivo em que a operação é executada.
Instruções para o compilador
Para instruir o compilador a diretiva #pragma pode ser utilizada. As instruções que podem ser utilizadas estão diretamente relacionadas com o compilador, sendo necessário consultar o seu manual para verificar os argumentos e instruções disponibilizados. A sua forma geral é:
#pragma <string>
A <string> representa a instrução e os argumentos informados.
Por exemplo, no compilador GCC temos a instrução message, que é responsável por exibir uma mensagem durante o processo de compilação.
void Test(void * ptrData)
{
#pragma message "Função Test: " __FILE__
if(ptrData == NULL)
{
printf("[%s - linha: %i]Ponteiro NULL!", __FILE__, __LINE__);
}
/*.....*/
}
Diagnóstico
Uma macro muito utilizada no processo de depuração é definida na biblioteca C padrão ASSERT.h. A macro é chamada de assert e tem como função testar se uma determinada condição é verdadeira, caso contrário o programa é encerrado.
void Test(void * ptrData)
{
assert(ptrData != NULL);
/*.....*/
}
No exemplo, se a condição testada é falsa o programa será encerrado com a seguinte mensagem:
Assertion failed: ptrData != NULL, file <arquivo>, line <número da linha>
Esses testes são úteis durante a depuração de um programa justamente para diagnóstico de possíveis falhas de execução devido a um estado inválido do programa, para isso a macro pode ser definida ou removida conforme o símbolo NDEBUG. Se a macro NDEBUG for definida então a macro assert() será ignorada e não terá efeito no programa.
Conclusão
Neste artigo foram apresentados, de maneira introdutória, alguns recursos do pré-processador que auxiliam o processo de depuração de aplicações e de diagnóstico de erros. Como foi demonstrado, com a utilização das asserções é possível verificar o estado de uma aplicação durante sua execução tornando-se uma ferramenta importante para encontrar bugs. Outra forma de diagnóstico pode ser realizada durante o processo de compilação, uma vez que as diretivas intrínsecas do pré-processador apresentam informações desse processo.
Na quarta parte deste artigo será apresentada uma técnica de expansão de macros chamada X macros.
Referências
[1] Livro: C, completo e total – 3ª edição revista e atualizada. Herbert Schildt.





Muito bom!
Obrigado, André!