2017-02-01 1 views
3

От 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.

+2

«Игнорирование объектов, объявленных вне внутреннего пространства ** пространства имен **». Ключевым словом является «пространство имен». Все идентификаторы в этом примере находятся в одном и том же пространстве имен. – AlexP

+0

@AlexP Почему переменная 'i' от' # 3' тогда имеет 'external' связь, а не' static', как указано в '# 1'? – SebNag

+0

«В этой программе есть три объекта с именем _i_. Объект с внутренней связью, введенный объявлением в глобальной области видимости (строка # 1), объект с автоматической продолжительностью хранения и отсутствие связей, введенных декларацией в строке # 2, и объект со статической продолжительностью хранения и внешнюю связь, введенную декларацией в строке №3 ». См. П. 3.5.9, почему 'extern int i' не то же самое _i_ как' static int i'. – AlexP

ответ

0

Я не понимаю ваше замешательство. Самая внутренняя охватывающая область пространства имен - это номер global namespace; первое и второе объявления соответствуют типу и имени, и, следовательно, объявление внешнего блока только наследует связь глобальной декларации (которая является внутренней из-за спецификатора static). Второе объявление области блока связано с первым; вы получаете идею.

+0

Я повторно отредактировал свой вопрос, возможно, теперь вы можете предоставить приемлемый ответ – SebNag

Смежные вопросы