Здравствуйте, DirtyGarry, Вы писали:
DG>Для переменной, объявленной на уровне файла, выражение
DG>DG>extern int i;
DG>
DG>«дает» глобальное время жизни, файловую область видимости и непонятно какое связывание (потому что это не определение).
Тут главное помнить, что у C и C++ связывание может различаться. Лаптев, например, уже "попался".
Это внешнее связывание (т.к. оно первое):
Committee Draft — May 6, 2005
6.2.2 Linkages of identifiers
4 For an identifier declared with the storage-class specifier extern in a scope in which a
prior declaration of that identifier is visible,23) if the prior declaration specifies internal or
external linkage, the linkage of the identifier at the later declaration is the same as the
linkage specified at the prior declaration. If no prior declaration is visible, or if the prior
declaration specifies no linkage, then the identifier has external linkage.
DG>Если связывание непонятно какое, я предположил, что программа
DG>DG>extern int i;
DG>void f(void)
DG>{
DG> i = i + 5;
DG>}
DG>static int i;
DG>
DG>скомпилируется. Но компилятор (gcc) со мной не согласился.
DG>Подскажите, пожалуйста, где я ошибся в своих рассуждениях.
Первая декларация объявляет внешнее связывание, последняя — внутренние. Согласно
6.2.2/7 If, within a translation unit, the same identifier appears with both internal and external
linkage, the behavior is undefined.
это неопределённое поведение. Т.е. даже если соберётся, то ничего не гарантировано.
Я не знаю как там в окончательном стандарте, но я бы требовал диагностику, а не это убойное UB.
DG>Приведенный пример, видимо, можно исправить только переместив определение переменной i в начало файла.
Если же такой порядок:
static int i;
extern int i;
то, согласно первой цитате (6.2.2/4) связывание у i — внутреннее.