Eu quero entender a ligação externa e a conexão interna e suas diferenças.
Eu também quero saber o significado de
const
variáveis vinculam internamente por padrão, a menos que seja declarado de outra formaextern
.
Quando você escreve um arquivo de implementação ( .cpp
, .cxx
, etc) o seu compilador gera uma unidade de tradução . Este é o arquivo de origem da sua implementação, além de todos os cabeçalhos que você possui #include
.
A ligação interna refere-se a tudo apenas no escopo de uma unidade de tradução .
Ligação externa refere-se a coisas que existem além de uma unidade de tradução específica. Em outras palavras, acessível por todo o programa , que é a combinação de todas as unidades de tradução (ou arquivos de objeto).
const
variáveis (assim como sua finalidade) é totalmente esquecida aqui.Como dudewat disse que a ligação externa significa que o símbolo (função ou variável global) está acessível em todo o programa e a conexão interna significa que ele está acessível apenas em uma unidade de tradução .
Você pode controlar explicitamente a ligação de um símbolo usando as palavras
extern
-static
chave e . Se a ligação não for especificada, a ligação padrão éextern
para não-const
símbolos estatic
(interna) paraconst
símbolos.Observe que, em vez de usar
static
para ligação interna, é melhor usar namespaces anônimos nos quais você também pode colocarclass
es. A ligação para namespaces anônimos mudou entre C ++ 98 e C ++ 11, mas o principal é que eles são inacessíveis a partir de outras unidades de tradução.fonte
extern
declaração correspondente no outro arquivo.static
. Diz-se que essas variáveis têm ligação interna .Considere o seguinte exemplo:
1.cpp
f
declaraf
como uma função com ligação externa (padrão). Sua definição deve ser fornecida posteriormente neste arquivo ou em outra unidade de tradução (fornecida abaixo).max
é definido como uma constante inteira. A ligação padrão para constantes é interna . Sua ligação é alterada para externo com a palavra-chaveextern
. Então agoramax
pode ser acessado em outros arquivos.n
é definido como uma variável inteira. A ligação padrão para variáveis definidas fora dos corpos das funções é externa .2.cpp
max
é declarado como tendo ligação externa . Uma definição correspondente paramax
(com ligação externa) deve aparecer em algum arquivo. (Como em 1.cpp)n
é declarado como tendo ligação externa .z
é definido como uma variável global com ligação interna .nCall
especificanCall
ser uma variável que retém seu valor entre as chamadas à funçãof()
. Diferentemente das variáveis locais com a classe de armazenamento automático padrão,nCall
serão inicializadas apenas uma vez no início do programa e não uma vez para cada chamada def()
. O especificador de classe de armazenamentostatic
afeta o tempo de vida da variável local e não seu escopo.NB: A palavra-chave
static
desempenha um papel duplo. Quando usado nas definições de variáveis globais, especifica a ligação interna . Quando usado nas definições das variáveis locais, especifica que o tempo de vida da variável será a duração do programa, em vez de ser a duração da função.Espero que ajude!
fonte
static
permite uma inicialização lenta e lenta (o que pode ser útil se você precisar de um objeto global, mas precisar controlar quando ele é construído devido a problemas com a ordem de construção global e não pode alocá-lo dinamicamente) o uso denew
esquemas de inicialização mais detalhados pode estar além do necessário para o objeto em questão; por implicação, isso é principalmente um problema em sistemas incorporados que usam C ++).Em termos de 'C' (como a palavra-chave estática tem um significado diferente entre 'C' e 'C ++')
Vamos falar sobre escopo diferente em 'C'
ESCOPO: É basicamente quanto tempo posso ver alguma coisa e até que ponto.
Variável local: o escopo está apenas dentro de uma função. Ele reside na área PILHA da RAM. O que significa que toda vez que uma função é chamada, todas as variáveis que fazem parte dessa função, incluindo argumentos de função, são criados recentemente e são destruídos quando o controle sai da função. (Como a pilha é liberada toda vez que a função retorna)
Variável estática: o escopo é para um arquivo. É acessível em qualquer lugar do arquivo
em que é declarado. Ele reside no segmento de dados da RAM. Como isso só pode ser acessado dentro de um arquivo e, portanto, ligação interna. Quaisquer
outros arquivos não podem ver esta variável. De fato, a palavra-chave STATIC é a única maneira pela qual podemos introduzir algum nível de dados ou função
ocultos em 'C'
Variável global: o escopo é para um aplicativo inteiro. É um formulário acessível em qualquer lugar do aplicativo. Variáveis globais também residem no segmento DATA, pois podem ser acessadas em todos os lugares do aplicativo e, portanto, EXTERNAL Linkage
Por padrão, todas as funções são globais. Caso precise ocultar algumas funções de um arquivo de fora, você pode prefixar a palavra-chave estática na função. :-)
fonte
Antes de falar sobre a questão, é melhor conhecer o termo unidade de tradução , programa e alguns conceitos básicos de C ++ (na verdade, linkage é um deles em geral) com precisão. Você também precisará saber o que é um escopo .
Vou enfatizar alguns pontos-chave, esp. aqueles que faltam nas respostas anteriores.
Linkage é uma propriedade de um nome , que é introduzida por uma declaração . Nomes diferentes podem denotar a mesma entidade (normalmente, um objeto ou uma função). Portanto, falar sobre vinculação de uma entidade geralmente não faz sentido, a menos que você tenha certeza de que a entidade será referida apenas pelo nome exclusivo de algumas declarações específicas (geralmente uma declaração).
Observe que um objeto é uma entidade, mas uma variável não é. Ao falar sobre o vínculo de uma variável, na verdade o nome da entidade denotada (que é introduzida por uma declaração específica) está em causa. O vínculo do nome está em um dos três: nenhum vínculo, vínculo interno ou vínculo externo.
Unidades de tradução diferentes podem compartilhar a mesma declaração por inclusão no cabeçalho / arquivo de origem (sim, é o texto da norma). Portanto, você pode consultar o mesmo nome em diferentes unidades de tradução. Se o nome declarado tiver ligação externa, a identidade da entidade referida pelo nome também será compartilhada. Se o nome declarado tiver ligação interna, o mesmo nome em diferentes unidades de conversão denota entidades diferentes, mas você pode consultá-la em escopos diferentes da mesma unidade de conversão. Se o nome não tiver vínculo, você simplesmente não poderá consultar a entidade de outros escopos.
(Opa ... Eu achei que o que eu digitei estava apenas repetindo o texto padrão ...)
Existem também outros pontos confusos que não são cobertos pela especificação da linguagem.
__attribute__
ou__declspec
) ou opções do compilador, e a imagem não é o programa inteiro ou o arquivo de objeto traduzido de uma unidade de tradução; portanto, nenhum conceito padrão pode descrevê-lo com precisão. Como símbolo não é um termo normativo em C ++, é apenas um detalhe de implementação, mesmo que as extensões relacionadas de dialetos possam ter sido amplamente adotadas.A regra de ligação da
const
variável de escopo do espaço para nome é algo especial (e particularmente diferente doconst
objeto declarado no escopo do arquivo na linguagem C, que também possui o conceito de ligação de identificadores). Como o ODR é imposto pelo C ++, é importante manter não mais de uma definição da mesma variável ou função ocorrida em todo o programa, exceto asinline
funções . Se não houver essa regra especialconst
, uma declaração mais simples deconst
variável com inicializadores (por exemplo= xxx
) em um cabeçalho ou arquivo de origem (geralmente um "arquivo de cabeçalho") incluído por várias unidades de tradução (ou incluídas por uma unidade de tradução mais de uma vez, embora raramente) em um programa viole o ODR, o que faz com queconst
variável como substituição de algumas macros do tipo objeto.fonte
Eu acho que a ligação interna e externa em C ++ fornece uma explicação clara e concisa:
fonte
A ligação determina se os identificadores com nomes idênticos se referem ao mesmo objeto, função ou outra entidade, mesmo que esses identificadores apareçam em unidades de conversão diferentes. A ligação de um identificador depende de como foi declarado. Existem três tipos de ligações:
Apenas C ++ : você também pode ter vínculo entre fragmentos de código C ++ e não C ++, que é chamado de vínculo de idioma .
Fonte: IBM Program Linkage
fonte
Basicamente
extern linkage
variável é visível em todos os arquivosinternal linkage
A variável é visível em um único arquivo.Explicar: variáveis const vinculadas internamente por padrão, a menos que declaradas de outra forma como externas
external linkage
const
variável global éinternal linkage
extern const
variável global extra éexternal linkage
Um material muito bom sobre ligação em C ++
http://www.goldsborough.me/c/c++/linker/2016/03/30/19-34-25-internal_and_external_linkage_in_c++/
fonte
Em C ++
Qualquer variável no escopo do arquivo e que não esteja aninhada dentro de uma classe ou função, é visível em todas as unidades de tradução em um programa. Isso é chamado de ligação externa porque, no momento do link, o nome fica visível para o vinculador em qualquer lugar, externo a essa unidade de tradução.
Variáveis globais e funções comuns têm ligação externa.
O objeto estático ou o nome da função no escopo do arquivo é local para a unidade de conversão. Isso é chamado de ligação interna
Vinculação refere-se apenas a elementos que possuem endereços no momento do link / carregamento; portanto, declarações de classe e variáveis locais não têm ligação.
fonte