От C++17 Standard Draft§ 3.5.6
:Рычажный функции объявлены как `extern` в блоке объема в соответствии со стандартом проекта C++ 17
Имя функции, объявленной в блоке сферы и имя переменной, объявленной по объему блока extern декларация имеет связь. Если есть видимое объявление объекта с привязкой с тем же именем и , тип, игнорируя объекты, объявленные вне самой внутренней охватывающей области пространства имен, Объявление области видимости блока объявляет эту же сущность и получает связь с предыдущей декларацией. Если имеется более одного такого объекта , программа плохо сформирована. В противном случае, если ни один соответствующий объект не найден, то блок сфера сущность получает внешнее связывание
Кроме того, существует пример, приведенный в стандарте:
static void f();
static int i = 0; // #1
void g() {
extern void f(); // internal linkage
int i; // #2 i has no linkage
{
extern void f(); // internal linkage
extern int i; // #3 external linkage
}
}
ли объявление функции третьего extern void f()
получает:
external
связь (из-за предшествующей декларацииextern void f()
)internal
связь (со второй декларациейf()
в блоке объеме выше получает внутреннюю связь от декларацииf()
в::
глобальном пространстве имен)- Или это плохо формируется, потому что есть более "более одного такое соответствие объекта "?
РЕДАКТИРОВАТЬ
main.cpp
#include <iostream>
extern void g();
void f() { std::cout << "main f() called" << std::endl; }
int main(){
g();
return 0;
}
test.cpp:
#include <iostream>
static void f() { std::cout << " test f() called" << std::endl; }
void g() {
extern void f();
{
extern void f();
f();
}
}
g()
вызывается в функции main()
в main.cpp
.
Составитель с gcc 5.4.0
г ++ -std = C++ 14 -Wall main.cpp test.cpp
Эстампов:
основной е() называется
Таким образом, gcc явно относится к вызову f()
с точностью до g()
wit h external
(вызов определения, содержащегося в файле main.cpp
).Либо комментарий в примере из стандарта неверен (объявление функции #3
не имеет взаимной привязки) или его ошибка компилятора от gcc
.
«Игнорирование объектов, объявленных вне внутреннего пространства ** пространства имен **». Ключевым словом является «пространство имен». Все идентификаторы в этом примере находятся в одном и том же пространстве имен. – AlexP
@AlexP Почему переменная 'i' от' # 3' тогда имеет 'external' связь, а не' static', как указано в '# 1'? – SebNag
«В этой программе есть три объекта с именем _i_. Объект с внутренней связью, введенный объявлением в глобальной области видимости (строка # 1), объект с автоматической продолжительностью хранения и отсутствие связей, введенных декларацией в строке # 2, и объект со статической продолжительностью хранения и внешнюю связь, введенную декларацией в строке №3 ». См. П. 3.5.9, почему 'extern int i' не то же самое _i_ как' static int i'. – AlexP