C ++ inline é totalmente diferente de C inline .
#include <iostream>
extern inline int i[];
int i [5];
struct c {
int function (){return 1;} //implicitly inline
static inline int j = 3; //explicitly inline
};
int main() {
c j;
std::cout << i;
}
inline
por si só afeta o compilador, montador e vinculador. É uma diretiva para o compilador dizendo que apenas emite um símbolo para esta função / dados se for usado na unidade de tradução e, se for, como os métodos de classe, diga ao assembler para armazená-los na seção .section .text.c::function(),"axG",@progbits,c::function(),comdat
ou .section .bss.i,"awG",@nobits,i,comdat
para dados. As instanciações de modelo também entram em seus próprios grupos de comdat.
Isto segue .section name, "flags"MG, @type, entsize, GroupName[, linkage]
. Por exemplo, o nome da seção é .text.c::function()
. axG
significa que a seção é alocável, executável e em um grupo, ou seja, um nome de grupo será especificado (e não há sinalizador M, portanto, nenhum tamanho será especificado); @progbits
significa que a seção contém dados e não está em branco; c::function()
é o nome do grupo e o grupo possuicomdat
linkage, o que significa que em todos os arquivos de objeto, todas as seções encontradas com esse nome de grupo marcadas com comdat serão removidas do executável final, exceto 1, isto é, o compilador garante que haja apenas uma definição na unidade de tradução e, em seguida, pede ao assembler para colocar em seu próprio grupo no arquivo de objeto (1 seção em 1 grupo) e, em seguida, o vinculador garantirá que, se algum arquivo de objeto tiver um grupo com o mesmo nome, inclua apenas um no .exe final. A diferença entre etc pelo montador devido a suas diretivas.inline
e não usar inline
agora é visível para o montador e, como resultado, o vinculador, porque não é armazenado no arquivo regular .data
ou.text
static inline
em uma classe significa que é uma definição de tipo e não declaração (permite que um membro estático seja definido na classe) e torne-o inline; agora se comporta como acima.
static inline
no escopo do arquivo afeta apenas o compilador. Isso significa para o compilador: somente emita um símbolo para esta função / dados se for usado na unidade de tradução e faça isso como um símbolo estático comum (armazene em.text /.data sem a diretiva .globl). Para o montador, agora não há diferença entre static
estatic inline
extern inline
é uma declaração que significa que você deve definir esse símbolo na unidade de tradução ou gerar erro do compilador; se estiver definido, trate-o como regular inline
e para o montador e vinculador não haverá diferença entre extern inline
e inline
, portanto, este é apenas um protetor de compilador.
extern inline int i[];
extern int i[]; //allowed repetition of declaration with incomplete type, inherits inline property
extern int i[5]; //declaration now has complete type
extern int i[5]; //allowed redeclaration if it is the same complete type or has not yet been completed
extern int i[6]; //error, redeclaration with different complete type
int i[5]; //definition, must have complete type and same complete type as the declaration if there is a declaration with a complete type
O conjunto acima, sem a linha de erro, é recolhido inline int i[5]
. Obviamente, se você fez extern inline int i[] = {5};
entãoextern
seria ignorado devido à definição explícita através da atribuição.
inline
em um espaço para nome, veja isso e isso