FAQ Lite
Funções inline

[ 9.1 ] O que caracteriza as funções inline ?
[ 9.2 ] Como as funções inline podem ajudar no equilíbrio entre segurança vs velocidade de execução?
[ 9.3 ] Porque eu devo usar funções inline ? Porque não usar simplesmente a velha macro #define ?
[ 9.4 ] Como você diz ao compilador para fazer uma função não-membro inline ?
[ 9.5 ] Como você determina ao compilador para fazer uma função membro inline ?
[ 9.6 ] Há alguma outra maneira de determinar ao compilador para fazer uma função membro inline ?
[ 9.7 ] As funções inline são garantidas quanto a tornar sua performance melhor?

[ 9.1 ] O que caracteriza as funções inline ?

Uma função inline é uma função cujo código é inserido dentro do arquivo fonte do chamador. Como uma macro #define, funções inline melhoram a performance porque evitam o overhead da execução do comando call e, especialmente, porque permitem ao compilador otimizar a chamada para a função.
Topo
[ 9.2 ] Como as funções inline podem ajudar no equilíbrio entre segurança vs velocidade de execução?

Em C, você consegue "structs encapsuladas" colocando um void* na struct, de modo que o void* aponta para os dados reais que são desconhecidos para os usuários da struct. Nesse caso os usuários da struct não sabem como interpretar os elementos apontados por void*, mas as funções de acesso processam o void* para o tipo apropriado, embora oculto. Isso resulta em uma forma de encapsulamento.

Infelizmente, esse mecanismo não cobre a segurança de tipos, e ainda impõe a chamada de uma função mesmo para acessar dados triviais da struct (se você permitisse acesso direto aos campos da struct, qualquer um e todo mundo estaria habilitado a acessá-la diretamente, já que todos teriam obrigatoriamente que saber como interpretar os elementos apontados pelo void*, o que resultaria ainda em mais dificuldade para se alterar a estrutura de dados).

O overhead das chamada de função é pequeno, mas deve ser considerado. As classes C++ permitem que as chamadas de função sejam expandidas inline. Isso permite que você tenha a segurança do encapsulamento, aliado a velocidade do acesso direto. Mais ainda, os tipos de dados dos parâmetros das funções inline são verificados pelo compilador, o que é uma vantagem até mesmo sobre as macros #define do C.

Topo
[ 9.3 ] Porque eu devo usar funções inline ? Porque não usar simplesmente a velha macro #define ?

Porque as macros #define são miseráveis.

Contrariamente às macros #define, funções inline evitam erros infames de macros, já que funções inline sempre calculam cada argumento exatamente uma vêz. Em outras palavras, invocar uma função inline é, semanticamente, o mesmo que invocar uma função regular, só que mais rápido.

    // A macro that returns the absolute value of i
    #define unsafe(i)  \
            ( (i) >= 0 ? (i) : -(i) )
    
    // An inline function that returns the absolute value of i
    inline
    int safe(int i)
    {
      return i >= 0 ? i : -i;
    }
    
    int f();
    
    void userCode(int x)
    {
      int ans;
    
      ans = unsafe(x++);   // Error! x is incremented twice
      ans = unsafe(f());   // Danger! f() is called twice
    
      ans = safe(x++);     // Correct! x is incremented once
      ans = safe(f());     // Correct! f() is called once
    } 
Também diferentemente das macros, os tipos dos argumentos são verificados, e as necessárias conversões são realizadas corretamente.

Macros são prejudiciais para sua saúde. Não as use, a menos que seja obrigado.

Topo
[ 9.4 ] Como você diz ao compilador para fazer uma função não-membro inline ?

Quando você declara uma função inline, ela se parece em tudo com uma função normal:

void f(int i, char c);

Mas quando você define uma função inline, você precede a definição da função com a palavra-chave inline e você põe a definição em um arquivo header.

inline
    void f(int i, char c)
    {
      // ...
    }

É usualmente imperativo que a definição da função, a parte entre {...} seja colocada em um arquivo header. Se você colocar a definição da função inline em um arquivo .cpp, e a função for chamada a partir de um outro arquivo .cpp, você receberá uma mensagem de erro do linker ("unresolved external")

Topo
[ 9.5 ] Como você determina ao compilador para fazer uma função membro
inline ?

Quando você declara uma função membro inline, ela se parece em tudo com uma função normal:

class Fred {
    public:
      void f(int i, char c)
        {
          // ...
        }
    };

Mas quando você define uma função inline, você precede a definição da função com a palavra-chave inline e você põe a definição em um arquivo header.

inline
    void Fred::f(int i, char c)
    {
      // ...
    }    

É usualmente imperativo que a definição da função, a parte entre {...} seja colocada em um arquivo header. Se você colocar a definição da função inline em um arquivo .cpp, e a função for chamada a partir de um outro arquivo .cpp, você receberá uma mensagem de erro do linker (unresolved external)

Topo
[ 9.6 ]  Há alguma outra maneira de determinar ao compilador para fazer uma função membro inline ?

Sim. Defina a função membro no próprio corpo da classe.

class Fred {
    public:
      void f(int i, char c)
        {
          // ...
        }
    };

Embora essa solução seja mais fácil para a pessoa que escreve o código da classe, é mais difícil para as pessoas que lêm o código, porque mistura o que a classe faz com como ela faz. Devido a essa mistura de coisas, é preferível definir funções membro fora do corpo da classe, usando-se a palavra-chave inline. A noção que mais faz sentido sobre esse assunto: em termos de orientação para reutilização de código, normalmente haverá várias pessoas que usam sua classe, mas há apenas uma pessoa que a constrói. Você mesmo! Assim, você deve fazer o que favorece a maioria dos usuários, e não o que interessa a poucos.

Topo
[ 9.7 ]  As funções inline são garantidas quanto a tornar sua performance melhor?

Não.

Atente para o fato de que o uso exagerado de funções inline pode inchar o seu código, o que pode ter um impacto negativo sobre a performance do programa, devido a necessidade de paginação do programa executável.

Topo Anterior Próximo Índice
C++ FAQ Lite
Copyright © 1991-98 by Marshall Cline Ph.D., cline@parashift.com
Tradução: Dagoberto Haele Arnaut

| Home | Bookmarks | Universidades | Para Saber mais | Universidades | WEB Directory | Mapa do site |