Цитата(XVR @ Jan 24 2012, 10:41)

Как видим иногда можно, и поэтому лучше всего никогда этого не делать
в том числе, по вкусу:
максимально об-static-овать все переменные, которые не нужны за пределами модуля
не лениться давать префиксы с именем модуля для глобальных
просто поменьше глобальных (C++ static-переменные класса с доступом через inline-методы рулят)
Цитата(XVR @ Jan 24 2012, 12:52)

это свойство именно языка С.
Стандарт С (99), глава 6.6.6: Linkages of identifiers
Так что для С слово extern и его отсуствие - одно и тоже

Вот...
Позволю себе немного дополнить. Правда, у меня другая нумерация, 6.2.2 (ISO/IEC 9899:1999 (E), слова draft нет, но нет и титульных страниц, надо бы обменяться файлами

)
Нажмите для просмотра прикрепленного файлаВыделенное в цитатах из стандарта у XVR звучит как то, что объявления переменной в
Код
int ii;
int ii;
int foo() { return ++i; }
int ii=2;
описывают
один объект с именем
ii (и gcc так и считает).
Т.е. тут даже инициализация есть, но одна. Это полетит в .data, и если в другом файле тоже будет
ii, то это будет конфликт (инициализация уже выступает не просто как объявление, но и как определение объекта). Похоже на работу с функцией — прототип можно указать в куче мест, но тело — в одном.
А вот если убрать инициализацию, то оно идёт не в .data, а в .comm с именем переменной. Чтобы в .bss, нужен ключ
-fno-common и тогда линкер выругается.
Мне тут не нравится только то, что проверка размеров не производится, если в одном файле
int c; а в другом
long c;, то линкер даже не заметит. Не его проблема. Очень напоминает COMMON-блоки фортрана :-)
А так — «фича». Несколько непривычно, но вон после ассемблера и integer promotion непривычно.
На проблемы с этим никогда не нарывался, возможно, в силу простой внимательности и простым правилам, которіе я напсиал в начале. В итоге даже ключик нигде не стоит и пришлось полезть глянуть, как он точно звучит (помню, что есть, забыл какой).