Что такое внешняя связь и внутренняя связь?


Я хочу понять внешнюю связь и внутреннюю связь и их разницу.

Я также хочу знать значение

const переменные внутренне связываются по умолчанию, если не объявлено иначе как extern.

9 285

9 ответов:

при записи файла реализации (.cpp,.cxx и т. д.) ваш компилятор генерирует ЕП. Это объектный файл из вашего файла реализации плюс все заголовки, которые вы #includeD в нем.

внутренняя перелинковка относится ко всему только в объеме единицы перевода.

внешняя связь относится к вещам, которые существуют за пределами конкретной единице перевода. Иначе говоря, доступно через всю программу, который представляет собой комбинацию всех единиц перевода (или объектных файлов).

как dudewat сказалвнешний связь означает, что символ (функция или глобальная переменная) доступен во всей вашей программе и внутренние связь означает, что она доступна только в одном ЕП.

вы можете явно управлять связью символа с помощью extern и static ключевые слова. Если связь не указана, то связь по умолчанию:extern для некурящихconst символы и static (внутренняя) для 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 

обратите внимание, что вместо того, чтобы использовать static для внутренней связи лучше использовать анонимные пространства имен в который вы также можете поместить class es. Связь для анонимных пространств имен изменилась между C++98 и C++11, но главное, что они недоступны из других единиц перевода.

namespace {
   int i; // external linkage but unreachable from other translation units.
   class invisible_to_others { };
}
  • глобальная переменная внешняя связь по умолчанию. Его область действия может быть расширена до файлов, отличных от содержащих его, путем предоставления соответствующего extern объявление в другом файле.
  • область действия глобальной переменной может быть ограничена файлом, содержащим ее объявление, путем префикса объявления ключевым словом статический. Такие переменные, как говорят,внутренняя перелинковка.

рассмотреть следующий пример:

1.cpp

void f(int i);
extern const int max = 10;
int n = 0;
int main()
{
    int a;
    //...
    f(a);
    //...
    f(a);
    //...
}
  1. сигнатура функции f объявляет f как функцию с внешняя связь(по умолчанию). Его определение должно быть представлено позже в этом файле или в другой единице перевода (приведенной ниже).
  2. max определяется как целочисленная константа. Связь по умолчанию для констант -внутренние. Его связь изменяется на внешнюю с ключевым словом extern. Так что теперь Макс может быть доступен в других файлах.
  3. N определяется как целочисленная переменная. Связь по умолчанию для переменных, определенных вне тел функций являются внешний.

2.cpp

#include <iostream>
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 (с внешней связью) должно появиться в каком-либо файле. (Как в 1.cpp)
  2. N будет объявлено внешняя связь.
  3. z это определена как глобальная переменная с внутренняя перелинковка.
  4. определение nCall определяет ncall как переменную, которая сохраняет свое значение при вызовах функции f (). В отличие от локальных переменных с классом автоматического хранения по умолчанию, nCall инициализируется только один раз при запуске программы и не один раз для каждого вызова f(). Спецификатор класса хранения статический влияет на время жизни локальной переменной, а не ее масштаб.

Примечание: ключевое слово статический играет двойную роль. При использовании в определениях глобальных переменных он указывает внутренняя перелинковка. При использовании в определениях локальных переменных он указывает, что время жизни переменной будет длительностью программы, а не продолжительностью функции.

надеюсь, что это поможет!

в терминах 'C '( потому что статическое ключевое слово имеет разное значение между 'C' & ' C++')

давайте поговорим о различных областях в 'C'

область: это в основном, как долго я могу видеть что-то и как далеко.

  1. локальная переменная: область видимости находится только внутри функции. Он находится в области стека ОЗУ. Это означает, что каждый раз, когда функция вызывается все переменные это часть этой функции, в том числе аргументы функции только что созданные и уничтожаются после того, как контроль выходит из функция. (Потому что стек сбрасывается каждый раз, когда функция возвращает)

  2. статическая переменная: область это для файла. Он доступен везде, где в файле
    в которой он заявлен. Он находится в сегменте данных ОЗУ. С это может быть доступно только внутри файла и, следовательно, внутренняя связь. Любой
    другие файлы не могут видеть эту переменную. На самом деле статическое ключевое слово-это единственный способ, которым мы можем ввести некоторый уровень данных или функция
    прячется в 'C'

  3. глобальная переменная: область действия для всего приложения. Это доступная форма каждый где находится приложение. Глобальные переменные также находятся в сегменте данных Так как он может быть доступен везде, где в применение и, следовательно, Внешняя связь

по умолчанию все функции являются глобальными. В случае, если вам нужно скрыть некоторые функции в файле извне, вы можете префикс статический ключевое слово для функции. : -)

прежде чем говорить о вопросе, лучше знать термин ЕП,программа и Основные понятия из C++ (на самом деле связь является одним из них в целом) точно. Вы также должны знать, что такое scope.

я подчеркну некоторые ключевые моменты, esp. те, что отсутствовали в предыдущих ответах.

связь - это свойство имя, который начинается с декларация. Разные имена могут обозначать одно и то же сущности (как правило, объект или функция). Так что говорить о связь сущности обычно нонсенс, если вы не уверены, что сущность будет называться только уникальным именем из некоторых конкретных объявлений (обычно одно объявление, хотя).

Примечание объект является юридическим лицом, а переменная is не. Говоря о связи переменной, на самом деле речь идет о имени обозначаемого объекта (который вводится конкретным объявлением). Связь имени находится в одном из трех: нет связи, внутренней связи или внешней связи.

различные единицы перевода могут совместно использовать одно и то же объявление по заголовку/исходному файлу (да, это формулировка стандарта). Таким образом, вы можете ссылаться на одно и то же имя в разных единицах перевода. Если объявленное имя имеет внешний связь, идентичность объекта, на который ссылается имя, также является общей. Если объявленное имя имеет внутреннюю связь, то одно и то же имя в разных единицах перевода обозначает разные сущности, но вы можете ссылаться на сущность в разных областях одной и той же единицы перевода. Если имя не имеет связи, вы просто не можете ссылаться на сущность из других областей.

(Упс... Я нашел, что я набрал было несколько просто повторяя стандартные формулировки ...)

там есть также некоторые другие запутанные моменты, которые не охватываются спецификацией языка.

  1. видимость (имя). Это также свойство объявленного имени, но со значением, отличным от linkage.
  2. видимость (побочного эффекта). Это не относится к данной теме.
  3. видимость (символа). Это понятие может быть используется в реальных реализациях. В таких реализациях символ с конкретная видимость в объектном (двоичном) коде обычно является целью, отображаемой из определения сущности, имена которой имеют ту же конкретную связь в исходном (C++) коде. Однако это обычно не гарантируется один к одному. Например, символ в образе динамической библиотеки может быть указан только совместно в этом образе внутренне из исходного кода (связанный с некоторыми расширениями, как правило,__attribute__ или __declspec) или параметры компилятора, и изображение не вся программа или объектный файл переведены из единицы перевода, таким образом, никакая стандартная концепция не может описать ее точно. Поскольку символ не является нормативным термином в C++, это всего лишь деталь реализации, хотя соответствующие расширения диалектов, возможно, были широко приняты.
  4. доступность. В C++ это обычно о свойство членов класса или базовых классов, что опять же является другой концепцией, не связанной с темой.
  5. глобальные. в C++, "глобальный" означает что-то глобальное пространство имен или область глобального пространства имен. последнее примерно эквивалентно объем файла на языке Си. Как в C, так и в C++ связь не имеет ничего общего с областью видимости, хотя область видимости (например, связь) также тесно связана с идентификатором (в C) или именем (в C++), введенным некоторым объявлением.

The правило связывания области пространства имен const переменная это что-то особенное (и особенно отличается от const объект объявленный в области видимости файла на языке C, который также имеет концепцию связывания идентификаторов). Так как ODR применяется C++,важно сохранить не более одного определения одной и той же переменной или функции во всей программе, за исключением inline функции. Если нет такого специального правила const, самое простое объявление const переменной с инициализаторами (например,= xxx) в заголовке или исходном файле (часто "заголовочный файл"), включенном несколько единиц перевода (или включенных одной единицей перевода более одного раза, хотя и редко) в программе будут нарушать ODR, что заставляет использовать const переменной в качестве замены какого-либо объекта-например, макросы невозможно.

Я думаю внутренняя и внешняя связь в C++ дает ясное и краткое объяснение:

единица перевода относится к реализации (.с./cpp файл) и все заголовок.( ч./ГЭС) файлы, которые он содержит. Если объект или функция внутри такая единица перевода имеет внутреннюю связь, то что конкретно символ виден только компоновщику в пределах этой единицы перевода. Если объект или функция имеет внешнюю связь, компоновщик также может ее видеть когда обработка других единиц перевода. Статическое ключевое слово, когда используется в глобальном пространстве имен заставляет символ иметь внутреннюю связь. Этот ключевое слово extern приводит к символу, имеющему внешнюю связь.

компилятор по умолчанию связывает символы таким образом, что:

Неконстантные глобальные переменные имеют внешнюю связь по умолчанию
Глобальные переменные Const имеют внутреннюю связь по умолчанию
Функции внешних связей, по умолчанию

в принципе

  • extern linkage переменная была видна во всех файлах
  • internal linkage переменная видна в одном файле.

объясните: переменные const внутренне связываются по умолчанию, если иное не объявлено как extern

  1. по умолчанию, глобальная переменная external linkage
  2. а, const глобальная переменная internal linkage
  3. дополнительно, extern const глобальная переменная external linkage

очень хороший материал о связи в C++

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

связь определяет, относятся ли идентификаторы с одинаковыми именами к одному и тому же объекту, функции или другому объекту, даже если эти идентификаторы отображаются в разных единицах перевода. Связь идентификатора зависит от того, как он был объявлен. Существует три типа связей:

  1. внутренняя перелинковка : идентификаторы можно увидеть только в переводе.
  2. внешняя связь : идентификаторы можно увидеть (и называют к) в других единицах.
  3. нет связи : идентификаторы можно увидеть только в области, в которой они определены. Связь не влияет на область видимости

только C++ : вы также можете иметь связь между фрагментами кода C++ и не C++, который называется язык связь.

источник : IBM Program Linkage

В C++

любая переменная в области файла, которая не вложена в класс или функцию, видна во всех единицах перевода в программе. Это называется внешняя связь потому что во время ссылки имя видно компоновщику везде, вне этой единицы перевода.

глобальные переменные и обычные функции внешних связей.

Static имя объекта или функции в области файла является локальным для единицы перевода. То есть называется как Внутренняя Перелинковка

связь относится только к элементам, которые имеют адреса во время соединения / загрузки; таким образом, объявления классов и локальные переменные не имеют связи.