Respostas:
inlineinstrui 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. inlineessencialmente 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.
staticrefere-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 statice static inlinedefinições de função.
O inlineespecificador (como a registerclasse 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.
inlinee registernã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 inlinedefiniçã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 registervariáveis qualificadas.
Pessoalmente, também uso a convenção para marcar staticdefiniçõ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 inlinefunção e static constobjeto, além de externdeclarações nos cabeçalhos.
Eu nunca escrevi uma inlinefunção com uma classe de armazenamento diferente de static.
inlinecomo 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 statice static inlinedifere de uma maneira como o compilador emite avisos sobre funções não utilizadas. Mais precisamente, quando você declara a staticfunçã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 staticdeve 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 inlinedeve 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 inlineinibe 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 inlinefunçã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, staticsignifica 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 inlinesignifica 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 inlinefunções não referenciadas da saída por padrão, mas manterão staticfunçõ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 inlinepara staticfunções em cabeçalhos.
inlineem definição? Você também implica não usá-lo para externfunções?
attribute((used))e seu uso para permitir que o asm faça referência a staticfunções e dados não referenciados .
staticrefere-se ao escopo. Em C, significa que a função / variável só pode ser usada dentro da mesma unidade de conversão.