O que é binding externa e binding interna?

Eu quero entender a binding externa e binding interna e sua diferença.

Eu também quero saber o significado de

Variáveis const internamente link por padrão, a menos que seja declarado de outra forma como extern .

   

Quando você escreve um arquivo de implementação ( .cpp , .cxx , etc), seu compilador gera uma unidade de tradução . Este é o arquivo object do seu arquivo de implementação mais todos os headers que você #include d nele.

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 através de todo o programa , que é a combinação de todas as unidades de tradução (ou arquivos de objects).

Como dudewat disse que a binding externa significa que o símbolo (function ou variável global) é acessível em todo o seu programa e a binding interna significa que ela só é acessível em uma unidade de tradução .

Você pode controlar explicitamente a vinculação de um símbolo usando as palavras-chave extern e static . Se a binding não for especificada, a binding padrão será extern para símbolos não const e static (interna) para símbolos const .

 // in namespace or global scope int i; // extern by default const int ci; // static by default extern const int eci; // explicitly extern static int si; // explicitly static // the same goes for functions (but there are no const functions) int foo(); // extern by default static int bar(); // explicitly static 

Observe que, em vez de usar static para binding interna, é melhor usar namespaces anônimos nos quais você também pode colocar class . A binding para namespaces anônimos foi alterada entre C ++ 98 e C ++ 11, mas o principal é que eles não podem ser acessados ​​de outras unidades de tradução.

 namespace { int i; // external linkage but unreachable from other translation units. class invisible_to_others { }; } 
  • Uma variável global possui binding externa por padrão. Seu escopo pode ser estendido para outros arquivos que não o contenham, dando uma declaração externa correspondente no outro arquivo.
  • O escopo de uma variável global pode ser restrito ao arquivo que contém sua declaração prefixando a declaração com a palavra-chave static . Essas variables ​​são chamadas de binding interna .

Considere o seguinte exemplo:

1. cpp

 void f(int i); extern const int max = 10; int n = 0; int main() { int a; //... f(a); //... f(a); //... } 
  1. A assinatura da function f declara f como uma function com binding externa (padrão). Sua definição deve ser fornecida posteriormente neste arquivo ou em outra unidade de tradução (dada abaixo).
  2. max é definido como uma constante inteira. A binding padrão para constantes é interna . Sua binding é alterada para externa com a palavra-chave extern . Então agora max pode ser acessado em outros arquivos.
  3. n é definido como uma variável inteira. A binding padrão para variables ​​definidas fora dos corpos de function é externa .

2.cpp

 #include  using namespace std; extern const int max; extern int n; static float z = 0.0; void f(int i) { static int nCall = 0; int a; //... nCall++; n++; //... a = max * z; //... cout < < "f() called " << nCall << " times." << endl; } 
  1. max é declarado como tendo binding externa . Uma definição correspondente para max (com binding externa) deve aparecer em algum arquivo. (Como em 1.cpp)
  2. n é declarado como tendo binding externa .
  3. z é definido como uma variável global com binding interna .
  4. A definição de nCall especifica nCall para ser uma variável que retém seu valor entre as chamadas para a function f (). Ao contrário das variables ​​locais com a class de armazenamento automático padrão, o nCall será inicializado apenas uma vez no início do programa e não uma vez para cada chamada de f (). O especificador de class de armazenamento estático afeta o tempo de vida da variável local e não seu escopo.

NB: A palavra-chave estática desempenha um papel duplo. Quando usado nas definições de variables ​​globais, especifica a binding interna . Quando usado nas definições das variables ​​locais, especifica que o tempo de vida da variável será a duração do programa, em vez de ser a duração da function.

Espero que ajude!

Em termos de ‘C’ (porque palavra-chave estática tem significado diferente entre ‘C’ e ‘C ++’)

Vamos falar sobre o escopo diferente em ‘C’

ESCOPO: É basicamente quanto tempo posso ver algo e até onde.

  1. Variável local: o escopo é somente dentro de uma function. Ele reside na área STACK da RAM. O que significa que toda vez que uma function é chamada, todas as variables ​​que fazem parte dessa function, incluindo argumentos de function, são recém criadas e são destruídas quando o controle sai da function. (Porque a pilha é liberada toda vez que a function retorna)

  2. Variável estática: o escopo disso é para um arquivo. É acessível a todos os lugares no arquivo
    em que é declarado. Ele reside no segmento de dados da RAM. Desde que isso só pode ser acessado dentro de um arquivo e, portanto, a vinculação interna. Qualquer
    outros arquivos não podem ver essa variável. De fato, a palavra-chave STATIC é a única maneira pela qual podemos introduzir algum nível de dados ou function
    escondendo-se em ‘C’

  3. Variável global: o escopo disso é para um aplicativo inteiro. É acessível a forma de todos os lugares da aplicação. Variáveis ​​globais também residem no segmento DATA, pois ele pode ser acessado em todo lugar na aplicação e, portanto, na conexão EXTERNA

Por padrão, todas as funções são globais. No caso, se você precisar ocultar algumas funções em um arquivo de fora, você pode prefixar a palavra-chave estática para a function. 🙂

Antes de falar sobre a questão, é melhor saber o termo unidade de tradução , programa e alguns conceitos básicos de C ++ (na verdade, a binding é um deles em geral). Você também terá que saber o que é um escopo .

Vou enfatizar alguns pontos-chave, esp. aqueles que faltam nas respostas anteriores.

Linkage é uma propriedade de um nome , que é introduzido por uma declaração . Nomes diferentes podem denotar a mesma entidade (normalmente, um object ou uma function). Portanto, falar de linkage de uma entidade geralmente é um absurdo, a menos que você tenha certeza de que a entidade só será referenciada pelo nome exclusivo de algumas declarações específicas (geralmente uma declaração, no entanto).

Observe que um object é uma entidade, mas uma variável não é. Ao falar sobre a binding de uma variável, na verdade, o nome da entidade denotada (que é introduzida por uma declaração específica) está em causa. A binding do nome está em um dos três: sem binding, binding interna ou binding externa.

Diferentes unidades de tradução podem compartilhar a mesma declaração por header / arquivo de origem (sim, é a redação do padrão). Então você pode referir o mesmo nome em diferentes unidades de tradução. Se o nome declarado tiver binding externa, a identidade da entidade referida pelo nome também será compartilhada. Se o nome declarado tiver binding interna, o mesmo nome em diferentes unidades de tradução indica entidades diferentes, mas você pode referenciar a entidade em diferentes escopos da mesma unidade de tradução. Se o nome não tiver vinculação, você simplesmente não poderá referenciar a entidade de outros escopos.

(Opa … eu encontrei o que eu digitei foi um pouco repetindo o texto padrão …)

Existem também alguns outros pontos confusos que não são cobertos pela especificação da linguagem.

  1. Visibilidade (de um nome). É também uma propriedade do nome declarado, mas com um significado diferente para a binding .
  2. Visibilidade (de um efeito colateral) . Isso não está relacionado a esse tópico.
  3. Visibilidade (de um símbolo). Essa noção pode ser usada por implementações reais . Em tais implementações, um símbolo com visibilidade específica no código de object (binário) é geralmente o destino mapeado da definição de entidade cujos nomes possuem a mesma binding específica no código de origem (C ++). No entanto, geralmente não é garantido um-para-um. Por exemplo, um símbolo em uma imagem de biblioteca dinâmica pode ser especificado apenas compartilhado nessa imagem internamente a partir do código-fonte (envolvido com algumas extensões, geralmente __attribute__ ou __declspec ) ou opções do compilador, e a imagem não é o programa inteiro ou o arquivo object traduzido de uma unidade de tradução, portanto nenhum conceito padrão pode descrevê-lo com precisão. Como o símbolo não é um termo normativo em C ++, ele é apenas um detalhe de implementação, embora as extensões relacionadas de dialetos possam ter sido amplamente adotadas.
  4. Acessibilidade. Em C ++, isso geralmente é uma propriedade de classs ou classs base , que é novamente um conceito diferente não relacionado ao tópico.
  5. Global. Em C ++, “global” refere-se a algo do espaço de nomes global ou do escopo do namespace global. Este último é aproximadamente equivalente ao escopo de arquivo na linguagem C. Tanto em C como em C ++, a binding não tem nada a ver com o escopo, embora o escopo (como linkage) também esteja fortemente relacionado a um identificador (em C) ou um nome (em C ++) introduzido por alguma declaração.

A regra de binding da variável const do namespace const é algo especial (e particularmente diferente do object const declarado no escopo do arquivo na linguagem C, que também possui o conceito de binding de identificadores). Como o ODR é imposto pelo C ++, é importante manter no máximo uma definição da mesma variável ou function ocorrida em todo o programa, exceto para funções inline . Se não houver essa regra especial de const , uma declaração mais simples de variável const com inicializadores (por exemplo, = xxx ) em um header ou um arquivo de origem (geralmente um “arquivo de header”) incluído por várias unidades de tradução (ou incluído por uma unidade de tradução mais de uma vez, embora raramente) em um programa violará o ODR, o que torna impossível usar a variável const como substituição de algumas macros de object.

Eu acho que External and External Linkage em C ++ fornece uma explicação clara e concisa:

Uma unidade de tradução refere-se a um arquivo de implementação (.c / .cpp) e a todos os arquivos de header (.h / .hpp) incluídos. Se um object ou function dentro de tal unidade de tradução tem binding interna, então esse símbolo específico é visível apenas para o vinculador dentro dessa unidade de tradução. Se um object ou function tiver binding externa, o vinculador também poderá vê-lo ao processar outras unidades de tradução. A palavra-chave estática, quando usada no espaço de nomes global, força um símbolo a ter uma binding interna. A palavra-chave externa resulta em um símbolo com binding externa.

O compilador padroniza a binding de símbolos de forma que:

Variáveis ​​globais não-constantes possuem binding externa por padrão
Variáveis ​​globais const têm binding interna por padrão
Funções têm binding externa por padrão

Basicamente

  • variável de extern linkage é visível em todos os arquivos
  • variável de internal linkage é visível em um único arquivo.

Explique: as variables ​​const codificam internamente por padrão, a menos que declaradas de outra forma como extern

  1. por padrão, a variável global é external linkage
  2. mas, variável global const é internal linkage
  3. extra, extern const variável global extern const é external linkage

Um bom material sobre linkage em C ++

http://www.goldsborough.me/c/c++/linker/2016/03/30/19-34-25-internal_and_external_linkage_in_c++/

O vínculo determina se os identificadores que possuem nomes idênticos se referem ao mesmo object, function ou outra entidade, mesmo que esses identificadores apareçam em diferentes unidades de tradução. A binding de um identificador depende de como ele foi declarado. Existem três tipos de ligações:

  1. Ligação interna : os identificadores só podem ser vistos em uma unidade de tradução.
  2. Ligação externa : os identificadores podem ser vistos (e referenciados) em outras unidades de tradução.
  3. Sem binding : os identificadores só podem ser vistos no escopo em que são definidos. A binding não afeta o escopo

C ++ apenas : Você também pode ter binding entre C ++ e fragments de código não-C ++, o que é chamado de binding de linguagem .

Fonte: IBM Program Linkage

Em C ++

Qualquer variável no escopo do arquivo e que não esteja aninhada dentro de uma class ou function, é visível em todas as unidades de tradução de um programa. Isso é chamado de binding externa porque, no momento do link, o nome é visível para o vinculador em qualquer lugar, externo a essa unidade de tradução.

Variáveis ​​globais e funções ordinárias possuem binding externa.

O object estático ou o nome da function no escopo do arquivo é local para a unidade de tradução. Isso é chamado de binding interna

Linkage refere-se apenas a elementos que possuem endereços no link / tempo de carregamento; assim, as declarações de class e as variables ​​locais não possuem vinculação.