A IMO cria a função de ter apenas um escopo da unidade de tradução.
Qual é a diferença entre a função "estática" e "estática em linha"?
Por que deve inline
ser colocado em um arquivo de cabeçalho, não em um .c
arquivo?
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
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 seminline
) 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, imoinline
, 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
estatic inline
definições de função.O
inline
especificador (como aregister
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
eregister
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: Umainline
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 deregister
variáveis qualificadas.Pessoalmente, também uso a convenção para marcar
static
definições de função nos cabeçalhosinline
, 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 estatic const
objeto, além deextern
declarações nos cabeçalhos.Eu nunca escrevi uma
inline
função com uma classe de armazenamento diferente destatic
.fonte
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
estatic inline
difere de uma maneira como o compilador emite avisos sobre funções não utilizadas. Mais precisamente, quando você declara astatic
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 parastatic 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. Estatic 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.fonte
warning: unused function 'function' [clang-diagnostic-unused-function]
umastatic inline
função ao criar comclang-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 ostatic
&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
fonte
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ãostatic
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 usarinline
parastatic
funções em cabeçalhos.fonte
inline
em definição? Você também implica não usá-lo paraextern
funções?attribute((used))
e seu uso para permitir que o asm faça referência astatic
funções e dados não referenciados .