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

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

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

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

Ответ 1

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

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

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

Ответ 2

Как 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. Связь между анонимными пространствами имен изменилась между С++ 98 и С++ 11, но главное, что они недоступны из других единиц перевода.

namespace {
   int i; // external linkage but unreachable from other translation units.
   class invisible_to_others { };
}

Ответ 3

  • По умолчанию глобальная переменная имеет внешнюю связь. Его область действия может быть расширена до файлов, отличных от содержащихся в нем, путем предоставления соответствующего внешнего объявления в другом файле.
  • Область глобальной переменной может быть ограничена файлом, содержащим его объявление, префикс объявления с ключевым словом static. Говорят, что такие переменные имеют внутреннюю связь.

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

1.cpp

void f(int i);
extern const int max = 10;
int n = 0;
int main()
{
    int a;
    //...
    f(a);
    //...
    f(a);
    //...
}
  • Подпись функции f объявляет f как функцию с внешней связью (по умолчанию). Его определение должно быть представлено позже в этом файле или в другой единицы перевода (см. Ниже).
  • max определяется как целочисленная константа. Связь по умолчанию для констант является внутренней. Его привязка изменяется на внешнее с ключевым словом extern. Таким образом, теперь max можно получить в других файлах.
  • 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;
}
  • Объявлено, что
  • max имеет внешнюю связь. Соответствующее определение max (с внешней связью) должно отображаться в каком-то файле. (Как в 1.cpp)
  • n объявлено, что имеет внешнюю связь.
  • z определяется как глобальная переменная с внутренней связью.
  • Определение nCall указывает nCall как переменную, которая сохраняет свое значение при вызове функции f(). В отличие от локальных переменных с классом автоматического хранения по умолчанию, nCall будет инициализироваться только один раз в начале программы, а не один раз для каждого вызова f(). Спецификатор класса хранения static влияет на время жизни локальной переменной, а не на ее область.

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

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

Ответ 4

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

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

СФЕРА: В основном, как долго я могу увидеть что-то и как далеко.

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

  • Статическая переменная: объем этого файла. Он доступен везде, где в файле
                  в котором он объявлен. Он находится в сегменте DATA оперативной памяти. поскольку               это может быть доступно только внутри файла и, следовательно, ВНУТРЕННЕЙ привязке. Любой
                  другие файлы не могут видеть эту переменную. Фактически ключевое слово STATIC - это               только способ, которым мы можем ввести некоторый уровень данных или функции
                  скрывается в 'C'

  • Глобальная переменная: масштаб этого для всего приложения. Это доступная форма для каждого               где приложение. Глобальные переменные также находятся в сегменте DATA               Поскольку доступ к нему возможен каждый раз в приложении и, следовательно,               ВНЕШНИЕ СВЯЗИ

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

Ответ 5

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

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

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

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

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

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

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

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

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

Ответ 6

Я думаю, что Внутренняя и Внешняя Связь в c++ дает ясное и краткое объяснение:

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

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

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

Ответ 7

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

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

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

Источник: Связь с программой IBM

Ответ 8

В принципе

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

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

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

Хороший материал о связях в С++

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

Ответ 9

В C++

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

Глобальные переменные и обычные функции имеют внешнюю связь.

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

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