Funções inline vs macros de pré-processador

Como uma function in-line é diferente de uma macro de pré-processador?

Macros de pré-processador são apenas padrões de substituição aplicados ao seu código. Eles podem ser usados ​​em praticamente qualquer lugar no seu código, porque eles são substituídos por suas expansões antes que qualquer compilation comece.

Funções inline são funções reais cujo corpo é diretamente injetado em seu local de chamada. Eles só podem ser usados ​​quando uma chamada de function é apropriada.

Agora, no que diz respeito ao uso de macros vs. funções embutidas em um contexto de function, esteja ciente de que:

  • As macros não são seguras, e podem ser expandidas independentemente de estarem sintaticamente corretas – a fase de compilation relatará erros resultantes de problemas de expansão de macro.
  • As macros podem ser usadas no contexto onde você não espera, resultando em problemas
  • As macros são mais flexíveis, pois podem expandir outras macros – enquanto as funções inline não fazem necessariamente isso.
  • As macros podem resultar em efeitos colaterais devido à sua expansão, uma vez que as expressões de input são copiadas onde quer que apareçam no padrão.
  • A function inline nem sempre tem a garantia de ser embutida – alguns compiladores fazem isso apenas em compilações de release ou quando são especificamente configurados para isso. Além disso, em alguns casos, o inlining pode não ser possível.
  • Funções inline podem fornecer escopo para variables ​​(particularmente as estáticas), macros de pré-processamento podem fazer isso apenas em blocos de código {…} e variables ​​estáticas não se comportarão exatamente da mesma maneira.

Primeiro, as macros de pré-processamento são apenas “copiar colar” no código antes da compilation. Portanto, não há verificação de tipo , e alguns efeitos colaterais podem aparecer

Por exemplo, se você quiser comparar dois valores:

#define max(a,b) ((a 

Os efeitos colaterais aparecem se você usar max(a++,b++) por exemplo ( a ou b será incrementado duas vezes). Em vez disso, use (por exemplo)

 inline int max( int a, int b) { return ((a 

A principal diferença é a verificação de tipos. O compilador irá verificar se o que você passa como valores de input é de tipos que podem ser passados ​​para a function. Isso não é verdade com macros de pré-processamento – elas são expandidas antes de qualquer verificação de tipo e isso pode causar graves e difíceis de detectar bugs.

Aqui estão vários outros pontos menos óbvios descritos.

A function Inline é expandida pelo compilador onde as macros são expandidas pelo Preprocessor, que é mera substituição textual.

  • Não há verificação de tipo durante a invocação de macro, enquanto a verificação de tipo é feita durante a chamada de function.

  • Resultados indesejados e ineficiência podem ocorrer durante a expansão macro devido à reavaliação de argumentos e ordem de operações. Por exemplo

     #define MAX(a,b) ((a)>(b) ? (a) : (b)) int i = 5, j = MAX(i++, 0); 

    resultaria em

     int i = 5, j = ((i++)>(0) ? (i++) : (0)); 
  • Os argumentos de macro não são avaliados antes da expansão de macro

     #define MUL(a, b) a*b int main() { // The macro is expended as 2 + 3 * 3 + 5, not as 5*8 printf("%d", MUL(2+3, 3+5)); return 0; } // Output: 16` 
  • A palavra-chave return não pode ser usada em macros para retornar valores como no caso de funções.

  • Funções embutidas podem ser sobrecarregadas

  • Os tokens passados ​​para macros podem ser concatenados usando o operador ## chamado operador Token-Colando.

  • As macros são geralmente usadas para reutilização de código, onde as funções embutidas são usadas para eliminar a sobrecarga de tempo (excesso de tempo) durante a chamada de function (evitando um salto para uma sub-rotina).

Para adicionar outra diferença àquelas já fornecidas: você não pode passar por um #define no depurador, mas pode percorrer uma function inline.

Macros estão ignorando namespaces. E isso os torna maus.

funções embutidas são semelhantes a macros (porque o código de function é expandido no ponto da chamada em tempo de compilation), as funções embutidas são analisadas pelo compilador, enquanto as macros são expandidas pelo pré-processador. Como resultado, existem várias diferenças importantes:

  • Funções inline seguem todos os protocolos de segurança de tipo aplicados em funções normais.
  • As funções embutidas são especificadas usando a mesma syntax que qualquer outra function, exceto que elas incluem a palavra-chave inline na declaração da function.
  • Expressões passadas como argumentos para funções embutidas são avaliadas uma vez.
  • Em alguns casos, expressões passadas como argumentos para macros podem ser avaliadas mais de uma vez. http://msdn.microsoft.com/pt-br/library/bf6bf4cf.aspx

  • Macros são expandidas no tempo de pré-compilation, você não pode usá-los para debugging, mas você pode usar funções embutidas.

bom artigo : http://www.codeguru.com/forum/showpost.php?p=1093923&postcount=1

;

Uma function inline manterá a semântica de valor, enquanto uma macro de pré-processamento apenas copia a syntax. Você pode obter bugs muito sutis com uma macro de pré-processador se usar o argumento várias vezes – por exemplo, se o argumento contiver uma mutação como “i ++”, ter essa execução duas vezes é uma grande surpresa. Uma function inline não terá esse problema.

Uma function inline se comporta sintaticamente como uma function normal, fornecendo segurança de tipo e um escopo para variables ​​locais de function e access a membros de class se for um método. Além disso, ao chamar methods in-line, você deve aderir a restrições privadas / protegidas.

No GCC (não tenho certeza sobre os outros), declarar uma function inline, é apenas uma dica para o compilador. Ainda cabe ao compilador no final do dia decidir se inclui ou não o corpo da function sempre que for chamado.

A diferença entre funções in-line e macros de pré-processador é relativamente grande. As macros de pré-processador são apenas uma substituição de texto no final do dia. Você desiste muito da capacidade do compilador executar a verificação na verificação de tipo nos argumentos e no tipo de retorno. A avaliação dos argumentos é muito diferente (se as expressões que você passar para as funções tiverem efeitos colaterais, você terá um tempo muito divertido de debugging). Existem diferenças sutis sobre onde as funções e macros podem ser usadas. Por exemplo, se eu tivesse:

 #define MACRO_FUNC(X) ... 

Onde MACRO_FUNC obviamente define o corpo da function. Cuidados especiais devem ser tomados para que seja executado corretamente em todos os casos, uma function pode ser usada, por exemplo, um MACRO_FUNC mal escrito causaria um erro em

 if(MACRO_FUNC(y)) { ...body } 

Uma function normal pode ser usada sem problemas.

Do ponto de vista da codificação, uma function inline é como uma function. Assim, as diferenças entre uma function inline e uma macro são as mesmas que as diferenças entre uma function e uma macro.

Do ponto de vista da compilation, uma function in-line é semelhante a uma macro. É injetado diretamente no código, não chamado.

Em geral, você deve considerar funções inline como sendo funções regulares com alguma otimização secundária misturada. E como a maioria das otimizações, cabe ao compilador decidir se realmente deseja aplicá-la. Muitas vezes, o compilador irá alegremente ignorar quaisquer tentativas do programador para inline uma function, por várias razões.

as funções inline se comportarão como uma chamada de function se houver alguma instrução iterativa ou recursiva, de modo a evitar a execução repetida de instruções. É bastante útil salvar a memory geral do seu programa.

 #include using namespace std; #define NUMBER 10 //macros are preprocessed while functions are not. int number() { return 10; } /*In macros, no type checking(incompatible operand, etc.) is done and thus use of micros can lead to errors/side-effects in some cases. However, this is not the case with functions. Also, macros do not check for compilation error (if any). Consider:- */ #define CUBE(b) b*b*b int cube(int a) { return a*a*a; } int main() { cout< 

As macros normalmente são mais rápidas que as funções, pois não envolvem sobrecarga de chamadas de function real.

Algumas desvantagens de macros: Não há verificação de tipo. Difícil de depurar, pois eles causam substituição simples. Macro não tem namespace, portanto, uma macro em uma seção do código pode afetar outra seção. Macros podem causar efeitos colaterais como mostrado no exemplo CUBE () acima.

Macros são geralmente um forro. No entanto, eles podem consistir em mais de uma linha. Não há tais restrições em funções.