Pergunta

Se eu definir uma função que não é membro em um cabeçalho, ela sempre será inLinada pelo compilador ou o compilador escolhe com base em suas heurísticas? Eu sei que __inline é apenas uma dica, é o mesmo com funções nos cabeçalhos?

Foi útil?

Solução

Lembre -se de que incluir algo de um cabeçalho não é diferente de apenas digitá -lo diretamente no arquivo de origem. Portanto, estar em um cabeçalho não faz diferença no que diz respeito ao compilador; Nunca soube que estava lá.

Portanto, quando você define uma função em um arquivo de cabeçalho e inclui esse arquivo de cabeçalho em um arquivo, é como se você tivesse acabado de digitar a função diretamente no arquivo. Então agora a pergunta é: "O compilador escolhe embutir as coisas baseadas nas heurísticas?"

A resposta é "depende do compilador". O padrão não garante o que fica inlinado ou não. Dito isto, qualquer compilador moderno será extremamente inteligente sobre o que ele inline, provavelmente com as heurísticas.

No entanto, chegamos a um ponto interessante. Imagine que você tem uma função em um cabeçalho e inclua esse cabeçalho em vários arquivos de origem. Você terá várias definições da função, nas unidades de tradução, e isso viola a regra de uma definição. Ergo, você receberá erros de compilação. (O erro do vinculador geralmente é algo parecido com: "Erro, função x já definida em y") O que você pode fazer é usar o inline Palavra -chave e você não viola mais o ODR.

A propósito __inline não é padrão. Ao contrário do seu post, geralmente é uma extensão do compilador que forças Inlining, não sugere isso. inline é a palavra -chave padrão, que originalmente se destinava a sugerir em Inlining. Como você diz, a maioria dos compiladores modernos o ignora completamente nesse sentido e seu único objetivo hoje em dia é dar às coisas o vínculo interno.

Outras dicas

De C ++ FAQ Lite:

Não importa como você designa uma função como embutida, é uma solicitação que o compilador possa ignorar: ele pode explicar alguns, todos, ou nenhuma das chamadas para uma função embutida.

Ele escolherá com base nas heurísticas. Certifique -se de declarar explicitamente em linha, caso contrário, poderá obter um erro de link de símbolo duplicado se incluir o cabeçalho em mais de uma unidade de compilação.

Se você definir Uma função com a ligação externa em um arquivo de cabeçalho e inclui -a em mais de uma unidade de tradução, você receberá um erro de compilação (mais precisamente: vinculador ERorr) para violação de uma regra de definição (ODR). Portanto, a resposta é "não": definir uma função em um arquivo de cabeçalho não será tomada pelo compilador como uma dica em inline e não o desculpará de observar os requisitos do ODR. Não apenas essas funções não estão garantidas para serem inlinadas, mas provavelmente seu programa nem sequer compilará.

Para definir uma função em um arquivo de cabeçalho e se safar, você deve dar uma ligação interna (declare -o static, e acabar com função separada em cada unidade de tradução) ou declarar explicitamente inline.

Quanto às heurísticas ... os compiladores modernos normalmente consideram praticamente qualquer função para inline (aplicando heurísticas), independentemente de onde é definida e se é declarado explicitamente inline ou não.

Não há mágica sobre funções nos cabeçalhos. O compilador nem sabe se uma função é definida em um cabeçalho ou não. (Como os cabeçalhos são efetivamente copiados/colados no arquivo de origem, você pode defini -lo em um cabeçalho, mas o compilador apenas o vê como parte da unidade de tradução)

Há também dois significados diferentes de "embutido" para estar ciente:

Uma função pode ser inlined conforme definido pelo padrão C ++: isso é feito prefixando a função com o inline Palavra-chave, ou se for uma função de membro, definindo-a no local dentro da definição da classe.

O efeito disso é

  • Informe ao vinculador que ele pode encontrar a definição de função em vários arquivos e deve apenas mesclá -los silenciosamente, em vez de jogar um erro
  • facilitar para o compilador executar o encaixe otimização.

O conflinador otimização Por outro lado, é simplesmente o ato de substituir uma chamada de função pelo corpo da função chamada, o que significa que essa otimização é realmente aplicada aos locais de chamada, não a funções. Uma função pode ser chamada normalmente de alguns lugares, mas inlinada em outros lugares. Uma chamada de função é inlinada quando o compilador se sente como, e é melhor separá -lo conceitualmente, inteiramente do primeiro significado de "embutido".

O compilador aplicará a otimização inline se, quando e onde parece. Ele usa muitas heurísticas para isso. As funções menores têm maior probabilidade de serem inlinhadas. Se determinar que um site de chamada específico será executado o suficiente com frequência, é mais provável que seja inlinado. Por fim, as heurísticas usadas são baseadas em "Will, melhorará ou degradam o desempenho". E geralmente é um juiz melhor do que os seres humanos, portanto, você não precisa saber quais heurísticas precisas ele usa. Em excesso apenas prejudicará o desempenho.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top