6.8 KiB
title | localeTitle |
---|---|
Preprocessors | Pré-processadores |
Pré-processadores em C / CPP
Como o nome sugere, os pré-processadores são programas que processam nosso código-fonte antes da compilação. Há vários passos envolvidos entre escrever um programa e executar um programa em C / C ++. Vamos dar uma olhada nestes passos antes de começarmos a aprender sobre os pré-processadores.
Você pode ver as etapas intermediárias no diagrama acima. O código fonte escrito pelos programadores é armazenado no arquivo program.c. Este arquivo é então processado por pré-processadores e um arquivo de código-fonte expandido é gerado programa nomeado. Este arquivo expandido é compilado pelo compilador e um arquivo de código de objeto é gerado chamado program.obj. Finalmente, o vinculador vincula esse arquivo de código de objeto ao código de objeto das funções de biblioteca para gerar o arquivo executável program.exe.
Os programas de pré-processador fornecem diretivas de pré-processadores que informam ao compilador para pré-processar o código-fonte antes de compilá-lo. Todas essas diretivas de pré-processador começam com um símbolo #
(hash). Esse símbolo ('#') no início de uma instrução em um programa C / C ++ indica que é uma diretiva de pré-processador. Podemos colocar essas diretivas pré-processador em qualquer parte do nosso programa. Exemplos de algumas diretivas de pré-processador são: #include
, #define
, #ifndef
etc.
Tipos de diretivas de pré-processador:
- Macros
- Inclusão de arquivos
- Compilação Condicional
- Outras diretivas
Macros:
As macros são uma parte do código em um programa que recebe algum nome. Sempre que esse nome é encontrado pelo compilador, o compilador substitui o nome pela parte real do código. A diretiva #define
é usada para definir uma macro.
#include<iostream>
#define LIMIT 3
int main()
{
for(int i=0; i < LIMIT; i++)
{
std::cout<<i<<" " ;
}
return 0;
}
Saída:
0 1 2
No programa acima, quando o compilador executa a palavra LIMIT
ele o substitui por 3. A palavra LIMIT
na definição de macro é chamada de modelo de macro e '3' é a expansão de macro.
Não deve haver ponto e vírgula (';') no final da definição macro. As definições de macro não precisam de ponto e vírgula para terminar.
Inclusão de arquivos:
Esse tipo de diretiva de pré-processador informa ao compilador para incluir um arquivo no programa de código-fonte. Existem dois tipos de arquivos que podem ser incluídos pelo usuário no programa:
- #### Arquivos de cabeçalho ou arquivos padrão: Esses arquivos contêm a definição de funções predefinidas como printf (),… scanf () etc. Esses arquivos devem ser incluídos para trabalhar com essas funções. … Funções diferentes são declaradas em diferentes arquivos de cabeçalho. Por exemplo… as funções de E / S padrão estão no arquivo 'iostream', enquanto as funções que… executam operações de string estão no arquivo 'string'.
Sintaxe:
#include< file_name >
onde file_name é o nome do arquivo a ser incluído. Os colchetes <
e >
dizem ao compilador para procurar o arquivo no diretório padrão.
- #### Arquivos definidos pelo usuário: Quando um programa se torna muito grande, é recomendável dividi-lo em arquivos menores e incluir sempre que necessário. Esses tipos de arquivos são arquivos definidos pelo usuário. Esses arquivos podem ser incluídos como: …
#include"filename"
Compilação Condicional:
As diretivas de compilação condicional são tipos de diretivas que ajudam a compilar uma parte específica do programa ou a pular a compilação de alguma parte específica do programa com base em algumas condições. Isso pode ser feito com a ajuda de dois comandos de pré-processamento ifdef
e endif
.
Sintaxe:
ifdef macro_name
statement1;
statement2;
statement3;
.
.
.
statementN;
endif
Se a macro com nome como 'macroname' for definida, o bloco de instruções será executado normalmente, mas se não for definido, o compilador simplesmente ignorará este bloco de instruções.
Outras diretivas:
Para além das directivas acima, existem mais duas directivas que não são normalmente utilizadas. Esses são:
- #####
#undef
Directiva: A diretiva#undef
é usada para indefinir uma macro existente. Esta diretiva funciona como:
Sintaxe:
#undef LIMIT
Usando esta declaração irá indefinir a macro LIMIT existente. Após esta declaração, cada declaração #ifdef LIMIT
será avaliada como falsa.
- #####
#pragma
directiva: Esta diretiva é uma diretiva de propósito especial e é usada para ativar ou desativar alguns recursos. Esse tipo de diretivas é específico do compilador, ou seja, elas variam de compilador para compilador. Algumas das diretivas ##pragma
são discutidas abaixo:
#pragma startup
e #pragma exit
:
Essas diretivas nos ajudam a especificar as funções necessárias para executar antes da inicialização do programa (antes que o controle passe para main ()) e logo antes da saída do programa (logo antes que o controle retorne de main ()).
#include<stdio.h>
void func1();
void func2();
#pragma startup func1
#pragma exit func2
void func1()
{
printf("Inside func1() ");
}
void func2()
{
printf("Inside func2() ");
}
int main()
{
printf("Inside main() ");
return 0;
}
Saída:
Inside func1() Inside main() Inside func2()
O código acima irá produzir a saída como indicado abaixo quando executado em compiladores GCC:
Saída:
Inside main()
Isso acontece porque o GCC não suporta a inicialização ou a saída #pragma. No entanto, você pode usar o código abaixo para uma saída similar em compiladores GCC.
#include<stdio.h>
void func1();
void func2();
void __attribute__((constructor)) func1();
void __attribute__((destructor)) func2();
void func1()
{
printf("Inside func1()\n");
}
void func2()
{
printf("Inside func2()\n");
}
int main()
{
printf("Inside main()\n");
return 0;
}
#pragma warn
directiva:
Esta diretiva é usada para ocultar a mensagem de aviso exibida durante a compilação. Podemos ocultar os avisos conforme mostrado abaixo:
#pragma warn -rvl
:
Essa diretiva oculta os avisos que são gerados quando uma função que deve retornar um valor não retorna um valor.
#pragma warn -par
:
Essa diretiva oculta os avisos que são gerados quando uma função não usa os parâmetros passados para ela.
#pragma warn -rch
:
Essa diretiva oculta os avisos que são gerados quando um código está inacessível. Por exemplo: qualquer código escrito após a declaração de retorno em uma função é inacessível.