Respostas:
inline
instrui o compilador a tentar incorporar o conteúdo da função no código de chamada em vez de executar uma chamada real.
Para pequenas funções chamadas com freqüência que podem fazer uma grande diferença de desempenho.
No entanto, isso é apenas uma "dica", e o compilador pode ignorá-la, e a maioria dos compiladores tentará "incorporar" mesmo quando a palavra-chave não for usada, como parte das otimizações, sempre que possível.
por exemplo:
static int Inc(int i) {return i+1};
.... // some code
int i;
.... // some more code
for (i=0; i<999999; i = Inc(i)) {/*do something here*/};
Esse loop restrito executará uma chamada de função em cada iteração, e o conteúdo da função é realmente significativamente menor que o código que o compilador precisa colocar para executar a chamada. inline
essencialmente instruirá o compilador a converter o código acima em um equivalente a:
int i;
....
for (i=0; i<999999; i = i+1) { /* do something here */};
Ignorando a chamada de função real e retornando
Obviamente, este é um exemplo para mostrar o ponto, não um pedaço de código real.
static
refere-se ao escopo. Em C, significa que a função / variável só pode ser usada dentro da mesma unidade de conversão.
static
(com ou sem inline
) pode estar no cabeçalho perfeitamente, não vejo razão para não. Modelos é para C ++, esta questão é de cerca de C.
inline
é bom estilo, imo
inline
, não instrui o compilador a fazer tentativas de inclusão. Apenas permite que o programador inclua o corpo da função em várias unidades de tradução sem violação do ODR. Um efeito colateral disso é que é torna possível para o compilador, quando ele iria inline função, para realmente fazer isso.
Por padrão, uma definição embutida é válida apenas na unidade de tradução atual.
Se a classe de armazenamento for extern
, o identificador possui ligação externa e a definição embutida também fornece a definição externa.
Se a classe de armazenamento for static
, o identificador possui ligação interna e a definição embutida é invisível em outras unidades de conversão.
Se a classe de armazenamento não for especificada, a definição em linha será visível apenas na unidade de conversão atual, mas o identificador ainda possui ligação externa e uma definição externa deve ser fornecida em uma unidade de conversão diferente. O compilador é livre para usar a definição interna ou externa se a função for chamada na unidade de tradução atual.
Como o compilador é livre para incorporar (e não incorporar) qualquer função cuja definição seja visível na unidade de tradução atual (e, graças às otimizações do tempo do link, mesmo em unidades de tradução diferentes, embora o padrão C não seja realmente responsável por que), para fins mais práticos, não há diferença entre static
e static inline
definições de função.
O inline
especificador (como a register
classe de armazenamento) é apenas uma dica do compilador, e o compilador é livre para ignorá-lo completamente. Os compiladores não otimizadores compatíveis com os padrões precisam apenas honrar seus efeitos colaterais, e os otimizadores compiladores farão essas otimizações com ou sem dicas explícitas.
inline
e register
não são inúteis, no entanto, pois instruem o compilador a gerar erros quando o programador escreve código que tornaria as otimizações impossíveis: Uma inline
definição externa não pode fazer referência a identificadores com ligação interna (pois eles não estavam disponíveis em uma unidade de tradução diferente) ou defina variáveis locais modificáveis com duração de armazenamento estático (como elas não compartilhariam o estado nas unidades de conversão) e você não poderá obter endereços de register
variáveis qualificadas.
Pessoalmente, também uso a convenção para marcar static
definições de função nos cabeçalhos inline
, pois o principal motivo para colocar definições de função nos arquivos de cabeçalho é torná-las inlináveis.
Em geral, eu apenas uso definições de static inline
função e static const
objeto, além de extern
declarações nos cabeçalhos.
Eu nunca escrevi uma inline
função com uma classe de armazenamento diferente de static
.
inline
como se realmente fosse aplicada a inlining é enganosa e indiscutivelmente incorreta. Nenhum compilador moderno o utiliza como uma dica para incorporar ou requerê-lo, a fim de permitir a inclusão de uma função.
Pela minha experiência com o GCC, sei disso static
e static inline
difere de uma maneira como o compilador emite avisos sobre funções não utilizadas. Mais precisamente, quando você declara a static
função e ela não é usada na unidade de tradução atual, o compilador produz um aviso sobre a função não utilizada, mas você pode inibi-lo alterando-o para static inline
.
Portanto, costumo pensar que isso static
deve ser usado em unidades de tradução e se beneficiar do compilador de verificação extra para encontrar funções não utilizadas. E static inline
deve ser usado em arquivos de cabeçalho para fornecer funções que podem ser alinhadas (devido à ausência de ligação externa) sem emitir avisos.
Infelizmente, não consigo encontrar nenhuma evidência para essa lógica. Mesmo na documentação do GCC, não consegui concluir que inline
inibe avisos de funções não utilizados. Eu apreciaria se alguém compartilhar links para a descrição disso.
warning: unused function 'function' [clang-diagnostic-unused-function]
uma static inline
função ao criar com clang-tidy
(v8.0.1), que é usado em outra unidade de tradução. Mas, definitivamente, esta é uma das melhores explicações e razões para combinar o static
& inline
!
Em C, static
significa que a função ou variável que você define pode ser usada apenas neste arquivo (ou seja, a unidade de compilação)
Portanto, static inline
significa a função embutida que pode ser usada apenas neste arquivo.
EDITAR:
A unidade de compilação deve ser a unidade de tradução
the compile unit
é algo que eu escrevi no erro, não existe tal coisa, a terminologia real étranslation unit
Uma diferença que não está no nível do idioma, mas no nível de implementação popular: certas versões do gcc removerão static inline
funções não referenciadas da saída por padrão, mas manterão static
funções simples mesmo que não sejam referenciadas. Não tenho certeza a quais versões isso se aplica, mas, do ponto de vista prático, significa que pode ser uma boa idéia sempre usar inline
para static
funções em cabeçalhos.
inline
em definição? Você também implica não usá-lo para extern
funções?
attribute((used))
e seu uso para permitir que o asm faça referência a static
funções e dados não referenciados .
static
refere-se ao escopo. Em C, significa que a função / variável só pode ser usada dentro da mesma unidade de conversão.