Я хочу понять внешнюю связь и внутреннюю связь и их различие.
Я также хочу знать значение
const
переменные внутренне связаны по умолчанию, если иное не объявлено какextern
.
Когда вы пишете файл реализации ( .cpp
и .cxx
т. Д.), Ваш компилятор генерирует модуль перевода . Это исходный файл из вашей реализации плюс все заголовки, которые вы #include
в нем поместили.
Внутренняя связь относится ко всему только в рамках единицы перевода .
Внешняя связь относится к вещам, которые существуют вне определенной единицы перевода. Другими словами, доступно через всю программу , которая является комбинацией всех единиц перевода (или объектных файлов).
const
переменных (а также о его назначении) здесь полностью отсутствует.Как сказал dudewat, внешняя связь означает, что символ (функция или глобальная переменная) доступен в вашей программе, а внутренняя связь означает, что он доступен только в одной единице перевода .
Вы можете явно контролировать связь символа, используя
extern
иstatic
ключевые слова. Если связь не указана, то связь по умолчанию предназначенаextern
для не-const
символов иstatic
(внутренняя) дляconst
символов.Обратите внимание, что вместо использования
static
внутренней связи лучше использовать анонимные пространства имен, в которые вы также можете поместитьclass
es. Связь между анонимными пространствами имен изменилась между C ++ 98 и C ++ 11, но главное, что они недоступны из других модулей перевода.источник
extern
объявления в другом файле.static
. Говорят, что такие переменные имеют внутреннюю связь .Рассмотрим следующий пример:
1.cpp
f
объявляетсяf
как функция с внешней связью (по умолчанию). Его определение должно быть предоставлено позже в этом файле или в другой единице перевода (приведено ниже).max
определяется как целочисленная константа. Связывание по умолчанию для констант является внутренним . Его связь меняется на внешнюю с ключевым словомextern
. Так что теперьmax
можно получить доступ в других файлах.n
определяется как целочисленная переменная. Связывание по умолчанию для переменных, определенных вне тел функций, является внешним .файле 2.cpp
max
объявляется внешняя связь . Соответствующее определение дляmax
(с внешней связью) должно появиться в некотором файле. (Как в 1.cpp)n
объявляется внешняя связь .z
будет определена как глобальная переменная с внутренней связью .nCall
указывает,nCall
что это переменная, которая сохраняет свое значение при вызовах функцииf()
. В отличие от локальных переменных со стандартным классом автоматического хранения,nCall
они будут инициализироваться только один раз в начале программы, а не один раз для каждого вызоваf()
. Спецификатор класса храненияstatic
влияет на время жизни локальной переменной, а не на ее область действия.NB . Ключевое слово
static
играет двойную роль. При использовании в определениях глобальных переменных он определяет внутреннюю связь . При использовании в определениях локальных переменных он указывает, что время жизни переменной будет продолжительностью программы, а не продолжительностью функции.Надеюсь, это поможет!
источник
static
допускает ленивую однократную инициализацию (что может быть полезно, если вам нужен объект global-ish, но нужно контролировать, когда он создается из-за проблем с глобальным порядком построения и не может динамически выделить его использованиеnew
более подробных схем инициализации может выходить за рамки того, что необходимо для рассматриваемого объекта, что подразумевает, что в основном это проблема встроенных систем, использующих C ++).В терминах «C» (потому что ключевое слово static имеет различное значение между «C» и «C ++»)
Давайте поговорим о различных сферах в «С»
СФЕРА ПРИМЕНЕНИЯ: Это в основном, как долго я могу что-то увидеть и как далеко.
Локальная переменная: область видимости только внутри функции. Он находится в области памяти STACK. Это означает, что каждый раз, когда функция вызывается, все переменные, которые являются частью этой функции, включая аргументы функции, создаются заново и уничтожаются, когда элемент управления выходит из функции. (Потому что стек очищается каждый раз, когда функция возвращается)
Статическая переменная: область действия для файла. Он доступен в любом месте файла,
в котором он объявлен. Он находится в сегменте памяти DATA. Поскольку это может быть доступно только внутри файла и, следовательно, внутренняя связь. Любые
другие файлы не могут видеть эту переменную. На самом деле ключевое слово STATIC - это единственный способ, которым мы можем ввести некоторый уровень данных или функции,
скрывающейся в «C».
Глобальная переменная: область действия для всего приложения. Это доступно из любой точки приложения. Глобальные переменные также находятся в сегменте DATA, так как к нему можно получить доступ из любого места приложения и, следовательно, ВНЕШНЕГО связывания
По умолчанию все функции являются глобальными. В случае, если вам нужно скрыть некоторые функции в файле извне, вы можете добавить к этой функции ключевое слово static. :-)
источник
Прежде чем говорить о данном вопросе, лучше точно знать термин единица перевода , программу и некоторые базовые понятия C ++ (на самом деле, одним из них является связывание). Вы также должны будете знать, что такое сфера .
Я подчеркну некоторые ключевые моменты, особенно те, которые отсутствуют в предыдущих ответах.
Связывание - это свойство имени , которое вводится объявлением . Разные имена могут обозначать одну и ту же сущность (как правило, объект или функцию). Поэтому говорить о связывании сущности, как правило, бессмысленно, если только вы не уверены, что сущность будет упоминаться только по уникальному имени из некоторых конкретных объявлений (обычно одного объявления, хотя).
Обратите внимание, что объект является сущностью, а переменная - нет. Говоря о связывании переменной, на самом деле речь идет об имени обозначенной сущности (которое вводится конкретной декларацией). Связь имени находится в одном из трех: нет связи, внутренней связи или внешней связи.
Различные единицы перевода могут совместно использовать одну и ту же декларацию путем включения заголовочного / исходного файла (да, это формулировка стандарта). Таким образом, вы можете ссылаться на одно и то же имя в разных единицах перевода. Если объявленное имя имеет внешнюю связь, идентичность объекта, на который ссылается имя, также является общей. Если объявленное имя имеет внутреннюю связь, одно и то же имя в разных единицах перевода обозначает разные сущности, но вы можете ссылаться на сущность в разных областях одной и той же единицы перевода. Если имя не имеет связи, вы просто не можете ссылаться на сущность из других областей.
(Упс ... Я обнаружил, что набрал несколько повторяющих стандартную формулировку ...)
Есть также некоторые другие запутанные моменты, которые не охватываются спецификацией языка.
__attribute__
или__declspec
) или параметров компилятора, и изображение не является целой программой или объектным файлом, переведенным из модуля перевода, поэтому ни одна стандартная концепция не может описать это точно. Поскольку символ не является нормативным термином в C ++, это всего лишь деталь реализации, даже если связанные расширения диалектов, возможно, получили широкое распространение.Правило связывания области пространства имен
const
переменного нечто особенное (и в частности , отличается отconst
объекта , объявленного в области видимости файла в C языке , который также имеет концепцию связывания идентификаторов). Поскольку ODR обеспечивается C ++, важно сохранить не более одного определения одной и той же переменной или функции во всей программе, кромеinline
функций . Если такого специального правила неconst
существует, простейшее объявлениеconst
переменной с инициализаторами (например,= xxx
в заголовке или в исходном файле (часто «заголовочный файл»)), включаемое несколькими единицами перевода (или включаемое одной единицей перевода более одного раза), хотя редко) в программе будет нарушаться ODR, что заставляет использоватьconst
переменная, так как замена некоторых объектоподобных макросов невозможна.источник
Я думаю, что Внутренняя и Внешняя Связь в C ++ дает ясное и краткое объяснение:
источник
Связывание определяет, относятся ли идентификаторы с одинаковыми именами к одному и тому же объекту, функции или другому объекту, даже если эти идентификаторы появляются в разных единицах перевода. Связь идентификатора зависит от того, как он был объявлен. Есть три типа связей:
Только C ++ : вы также можете иметь связь между фрагментами кода C ++ и не-C ++, что называется языковой связью .
Источник: IBM Program Linkage
источник
В принципе
extern linkage
переменная видна во всех файлахinternal linkage
переменная видна в одном файле.Пояснение: переменные const внутренне связаны по умолчанию, если иное не объявлено как extern
external linkage
const
глобальная переменнаяinternal linkage
extern const
глобальная переменнаяexternal linkage
Довольно хороший материал о связях в C ++
http://www.goldsborough.me/c/c++/linker/2016/03/30/19-34-25-internal_and_external_linkage_in_c++/
источник
В C ++
Любая переменная в области видимости файла, которая не вложена в класс или функцию, видна во всех единицах перевода в программе. Это называется внешней связью, потому что во время ссылки имя видно компоновщику повсюду, вне этой единицы перевода.
Глобальные переменные и обычные функции имеют внешнюю связь.
Статическое имя объекта или функции в области видимости файла является локальным для единицы перевода. Это называется внутренней связью
Связывание относится только к элементам, которые имеют адреса во время ссылки / загрузки; таким образом, объявления классов и локальные переменные не имеют связи.
источник