Pré-processadores Objective-C

o Objective-C Preprocessornão faz parte do compilador, mas é uma etapa separada no processo de compilação. Em termos simplistas, um pré-processador Objective-C é apenas uma ferramenta de substituição de texto e instrui o compilador a fazer o pré-processamento necessário antes da compilação real. Vamos nos referir ao Pré-processador Objective-C como OCPP.

Todos os comandos do pré-processador começam com um símbolo de cerquilha (#). Deve ser o primeiro caractere não vazio e, para facilitar a leitura, uma diretiva do pré-processador deve começar na primeira coluna. A seção a seguir lista todas as diretivas importantes do pré-processador -

Sr. Não. Diretriz e descrição
1

#define

Substitui uma macro de pré-processador

2

#include

Insere um cabeçalho específico de outro arquivo

3

#undef

Indefine uma macro de pré-processador

4

#ifdef

Retorna verdadeiro se esta macro estiver definida

5

#ifndef

Retorna verdadeiro se esta macro não estiver definida

6

#if

Testa se uma condição de tempo de compilação é verdadeira

7

#else

A alternativa para #if

8

#elif

#else an #if em uma instrução

9

#endif

Termina o pré-processador condicional

10

#error

Imprime mensagem de erro em stderr

11

#pragma

Emite comandos especiais para o compilador usando um método padronizado

Exemplos de pré-processadores

Analise os exemplos a seguir para entender as várias diretivas.

#define MAX_ARRAY_LENGTH 20

Esta diretiva diz ao OCPP para substituir as instâncias de MAX_ARRAY_LENGTH por 20. Use #define para constantes para aumentar a legibilidade.

#import <Foundation/Foundation.h>
#include "myheader.h"

Essas diretivas dizem ao OCPP para obter fundamentos.h de Foundation Frameworke adicione o texto ao arquivo de origem atual. A próxima linha diz ao OCPP para obtermyheader.h do diretório local e adicione o conteúdo ao arquivo de origem atual.

#undef  FILE_SIZE
#define FILE_SIZE 42

Isso diz ao OCPP para indefinir FILE_SIZE existente e defini-lo como 42.

#ifndef MESSAGE
   #define MESSAGE "You wish!"
#endif

Isso diz ao OCPP para definir MESSAGE apenas se MESSAGE ainda não estiver definida.

#ifdef DEBUG
   /* Your debugging statements here */
#endif

Isso diz ao OCPP para fazer o processo das instruções incluídas se DEBUG for definido. Isso é útil se você passar o sinalizador -DDEBUG para o compilador gcc no momento da compilação. Isso definirá DEBUG, para que você possa ativar e desativar a depuração durante a compilação.

Macros Predefinidas

ANSI C define várias macros. Embora cada um esteja disponível para seu uso na programação, as macros predefinidas não devem ser modificadas diretamente.

Sr. Não. Macro e descrição
1

__DATE__

A data atual como um literal de caractere no formato "MMM DD AAAA"

2

__TIME__

A hora atual como um literal de caractere no formato "HH: MM: SS"

3

__FILE__

Contém o nome do arquivo atual como um literal de string.

4

__LINE__

Contém o número da linha atual como uma constante decimal.

5

__STDC__

Definido como 1 quando o compilador está em conformidade com o padrão ANSI.

Vamos tentar o seguinte exemplo -

#import <Foundation/Foundation.h>

int main() {
   NSLog(@"File :%s\n", __FILE__ );
   NSLog(@"Date :%s\n", __DATE__ );
   NSLog(@"Time :%s\n", __TIME__ );
   NSLog(@"Line :%d\n", __LINE__ );
   NSLog(@"ANSI :%d\n", __STDC__ );
   
   return 0;
}

Quando o código acima em um arquivo main.m é compilado e executado, ele produz o seguinte resultado -

2013-09-14 04:46:14.859 demo[20683] File :main.m
2013-09-14 04:46:14.859 demo[20683] Date :Sep 14 2013
2013-09-14 04:46:14.859 demo[20683] Time :04:46:14
2013-09-14 04:46:14.859 demo[20683] Line :8
2013-09-14 04:46:14.859 demo[20683] ANSI :1

Operadores de pré-processador

O pré-processador Objective-C oferece os seguintes operadores para ajudá-lo na criação de macros -

Continuação da macro (\)

Uma macro geralmente deve estar contida em uma única linha. O operador de continuação de macro é usado para continuar uma macro que é muito longa para uma única linha. Por exemplo -

#define  message_for(a, b)  \
   NSLog(@#a " and " #b ": We love you!\n")

Stringize (#)

O operador stringize ou sinal numérico ('#'), quando usado em uma definição de macro, converte um parâmetro de macro em uma constante de string. Este operador pode ser usado apenas em uma macro que tenha um argumento ou lista de parâmetros especificada. Por exemplo -

#import <Foundation/Foundation.h>

#define  message_for(a, b)  \
   NSLog(@#a " and " #b ": We love you!\n")

int main(void) {
   message_for(Carole, Debra);
   return 0;
}

Quando o código acima é compilado e executado, ele produz o seguinte resultado -

2013-09-14 05:46:14.859 demo[20683] Carole and Debra: We love you!

Colar token (##)

O operador de colagem de token (##) em uma definição de macro combina dois argumentos. Ele permite que dois tokens separados na definição da macro sejam unidos em um único token. Por exemplo -

#import <Foundation/Foundation.h>

#define tokenpaster(n) NSLog (@"token" #n " = %d", token##n)

int main(void) {
   int token34 = 40;
   
   tokenpaster(34);
   return 0;
}

Quando o código acima é compilado e executado, ele produz o seguinte resultado -

2013-09-14 05:48:14.859 demo[20683] token34 = 40

Como aconteceu, porque este exemplo resulta na seguinte saída real do pré-processador -

NSLog (@"token34 = %d", token34);

Este exemplo mostra a concatenação do token ## n no token34 e aqui usamos ambos stringize e token-pasting.

O operador definido ()

O pré-processador definedoperador é usado em expressões constantes para determinar se um identificador é definido usando #define. Se o identificador especificado for definido, o valor é verdadeiro (diferente de zero). Se o símbolo não estiver definido, o valor é falso (zero). O operador definido é especificado da seguinte forma -

#import <Foundation/Foundation.h>

#if !defined (MESSAGE)
   #define MESSAGE "You wish!"
#endif

int main(void) {
   NSLog(@"Here is the message: %s\n", MESSAGE);  
   return 0;
}

Quando o código acima é compilado e executado, ele produz o seguinte resultado -

2013-09-14 05:48:19.859 demo[20683] Here is the message: You wish!

Macros Parametrizadas

Uma das funções poderosas do OCPP é a capacidade de simular funções usando macros parametrizadas. Por exemplo, podemos ter algum código para elevar ao quadrado um número da seguinte forma -

int square(int x) {
   return x * x;
}

Podemos reescrever o código acima usando uma macro da seguinte maneira -

#define square(x) ((x) * (x))

Macros com argumentos devem ser definidos usando o #defineantes que eles possam ser usados. A lista de argumentos está entre parênteses e deve seguir imediatamente o nome da macro. Espaços não são permitidos entre o nome da macro e parênteses de abertura. Por exemplo -

#import <Foundation/Foundation.h>

#define MAX(x,y) ((x) > (y) ? (x) : (y))

int main(void) {
   NSLog(@"Max between 20 and 10 is %d\n", MAX(10, 20));  
   return 0;
}

Quando o código acima é compilado e executado, ele produz o seguinte resultado -

2013-09-14 05:52:15.859 demo[20683] Max between 20 and 10 is 20