Diretiva #define (C/C++)
A diretiva #define cria uma macro, que é a associação de um identificador ou identificador parametrizado com uma cadeia de caracteres de token. Após a definição da macro, o compilador pode substituir a cadeia de caracteres de token para cada ocorrência do identificador no arquivo de origem.
Sintaxe
#define identificador token-stringopt
#define identificador ( identificadoropt, ... , identificadoropt ) token-stringopt
Comentários
A diretiva #define faz com que o compilador substitua token-string para cada ocorrência do identificador no arquivo de origem. O identificador será substituído apenas quando formar um token. Ou seja, o identificador não será substituído se ele aparecer em um comentário, em uma cadeia de caracteres ou como parte de um identificador mais longo. Para obter mais informações,confira Tokens.
O argumento token-string consiste em uma série de tokens, como palavras-chave, constantes ou instruções completas. Um ou mais caracteres de espaço em branco devem separar o token-string do identificador. Esse espaço em branco não é considerado parte do texto substituído, nem de qualquer espaço em branco que siga o último token do texto.
Um #define
sem um token-string remove as ocorrências do identificador do arquivo de origem. O identificador permanecerá definido e poderá ser testado usando as diretivas #if defined
e #ifdef
.
A segunda forma de sintaxe define uma macro do tipo função com parâmetros. Essa forma aceita uma lista opcional de parâmetros que devem aparecer entre parênteses. Depois que a macro é definida, cada ocorrência subsequente de identifier( identifieropt, ..., identifieropt ) será substituída por uma versão do argumento token-string que tem argumentos reais substituídos por parâmetros formais.
Nomes de parâmetros formais aparecem em token-string para marcar os locais onde os valores reais são substituídos. Cada nome de parâmetro pode aparecer várias vezes em token-string e os nomes podem aparecer em qualquer ordem. O número de argumentos na chamada deve coincidir com o número de parâmetros na definição da macro. O uso liberal dos parênteses garante que os argumentos complexos reais sejam interpretados corretamente.
Os parâmetros formais na lista são separados por vírgulas. Cada nome da lista deve ser exclusivo, e a lista deve ser colocada entre parênteses. Nenhum espaço poderá separar o identificador e o parêntese de abertura. Use a concatenação de linha, coloque uma barra invertida (\
) imediatamente antes do caractere de nova linha, para políticas longas em várias linhas de código-fonte. O escopo de um nome de parâmetro formal se estende até a nova linha que termina em token-string.
Quando uma macro é definida na segunda forma de sintaxe, as instâncias textuais subsequentes seguidas por uma lista de argumentos indicam uma chamada de macro. Os argumentos reais que seguem uma instância de identificador no arquivo de origem correspondem aos parâmetros formais correspondentes na definição da macro. Cada parâmetro formal em token-string que não é precedido por um operador stringizing (#
), charizing (#@
) ou token-pasting (##
), ou não acompanhado por um operador ##
, é substituído pelo argumento real correspondente. As macros no argumento real são expandidas antes da política substituir o parâmetro formal. (Os operadores são descritos em Operadores de pré-processador.)
Os seguintes exemplos de macros com argumentos ilustram a segunda forma da sintaxe#define:
// Macro to define cursor lines
#define CURSOR(top, bottom) (((top) << 8) | (bottom))
// Macro to get a random integer with a specified range
#define getrandom(min, max) \
((rand()%(int)(((max) + 1)-(min)))+ (min))
Os argumentos com efeitos colaterais às vezes fazem com que as macros produzam resultados inesperados. Um determinado parâmetro formal poderá aparecer mais de uma vez em token-string. Se o parâmetro formal for substituído por uma expressão com efeitos colaterais, a expressão, com seus efeitos colaterais, poderá ser avaliada mais de uma vez. (Confira os exemplos em Operador token-pasting (##).)
A política #undef
faz com que a definição de pré-processador de um identificador seja esquecida. Confira A diretiva #undef Para obter mais informações.
Se o nome da macro que está sendo definida ocorrer em token-string (mesmo como resultado de outra expansão de macro), ela não será expandida.
Uma segunda #define para uma macro com o mesmo nome gerará um aviso, a menos que a segunda sequência de token seja idêntica à primeira.
Seção específica da Microsoft
O Microsoft C/C++ permite que você redefina uma macro se a nova definição for sintaticamente idêntica à definição original. Ou seja, as duas definições podem ter nomes de parâmetro diferentes. Esse comportamento difere do ANSI C, que exige que as duas definições sejam lexicalmente idênticas.
Por exemplo, as duas macros a seguir são idênticas, exceto os nomes de parâmetro. ANSI C não permite essa redefinição, mas o Microsoft C/C++ compila sem erros.
#define multiply( f1, f2 ) ( f1 * f2 )
#define multiply( a1, a2 ) ( a1 * a2 )
Por outro lado, as duas macros a seguir não são idênticas e irão gerar um aviso no Microsoft C/C++.
#define multiply( f1, f2 ) ( f1 * f2 )
#define multiply( a1, a2 ) ( b1 * b2 )
Fim da seção específica da Microsoft
Este exemplo ilustra a diretiva #define:
#define WIDTH 80
#define LENGTH ( WIDTH + 10 )
A primeira declaração define o identificador WIDTH
como a constante inteira 80 e define LENGTH
em termos de WIDTH
e da constante inteira 10. Cada ocorrência de LENGTH
é substituída por (WIDTH + 10
). Por sua vez, cada ocorrência de WIDTH + 10
é substituída pela expressão (80 + 10
). Os parênteses em torno de WIDTH + 10
são importantes porque controlam a interpretação em instruções como esta:
var = LENGTH * 20;
Após o estágio de pré-processamento, a instrução se torna:
var = ( 80 + 10 ) * 20;
que é avaliado em 1800. Sem parênteses, o resultado é:
var = 80 + 10 * 20;
que avalia para 280.
Seção específica da Microsoft
Definir macros e constantes com a opção do compilador /D terá o mesmo efeito que usar uma diretiva de pré-processamento #define no início do arquivo. Até 30 macros podem ser definidas usando a opção /D.
Fim da seção específica da Microsoft