области видимости. Специальные соглашения действуют на имена, введенные при
описании параметров функции ($$R.8.2.5) и в описаниях friend ($$R.11.4). Имя может
быть скрыто явным описанием того же имени в объемлющем блоке или классе.
Скрытое имя члена класса все-таки можно использовать, если оно предваряется
именем класса, к которому применена операция :: ($$R.4.1, $$R.9.4, $$R.10). Скрытое
имя объекта, функции, типа или элемента перечисления с файловой областью
видимости можно использовать, если оно предваряется унарной операцией :: ($
$R.5.1). В дополнении к этому, имя класса ($$R.9.1) может быть скрыто именем
объекта, функции или элемента перечисления, имеющего ту же область видимости.
Если класс и объект, или функция, или элемент перечисления описаны (в любом
порядке) с одинаковым именем в одной области видимости, то имя класса становится
скрытым. Имя класса, скрытое в локальной области видимости или в области
видимости класса именем объекта, функции или элемента перечисления, все-таки
можно использовать, если предварить его подходящей спецификацией class, struct или
union ($$R.7.1.6). Аналогично, скрытое имя элемента перечисления можно
использовать, если предварить его спецификацией типа enum ($$R.7.1.6). В $$R.10.4
приводится сводка правил области видимости. Моментом описания имени считается
момент завершения описателя имени ($$R.8), предшествующей части инициализации
(если она есть). Например, int x = 12; { int x = x; } Здесь второе x инициализируется
своим собственным (неопределенным) значением. Моментом описания элемента
перечисления считается момент сразу после появления его идентификатора,
например: enum { x = x }; Здесь элемент перечисления x опять инициализируется
своим собственным (неопределенным) значением.
R.3.3 Программа и связывание
Программа состоит из одного или нескольких файлов, связываемых вместе ($$R.2).
Файл состоит из последовательности описаний. Имя с файловой областью видимости,
которое явно описано как static, является локальным в своей единице трансляции и
может использоваться для именования объектов, функций и т.п. в других единицах
трансляции. Говорят, что такие имена имеют внутреннее связывание. Имя с файловой
областью видимости, которое явно описано со спецификацией inline, является
локальным в своей единице трансляции. Имя с файловой областью видимости, которое
явно описано со спецификацией const и не описано явно как extern, считается
локальным в своей единице трансляции. То же верно для имени класса, которое не
использовалось в нелокальных для данной единицы трансляции описаниях объекта,
функции или класса, и который не имеет статических членов ($$R.9.4), не имеет
функций-членов, кроме подстановок ($$R.9.3.2). Всякое описание некоторого имени с
файловой областью видимости, которое не описано одним из перечисленных способов
так, чтобы иметь внутреннее связывание, в многофайловой программе обозначает
один и тот же объект ($$R.3.7), функцию ($$R.8.2.5) или класс ($$R.9). Такие имена
называются внешними или говорят, что они имеют внешнее связывание. В частности,
поскольку нельзя описать имя класса как static, всякое употребление имени
некоторого класса с файловой областью видимости, который (класс) использовался
для описания объекта или функции с внешним связыванием, или же который имеет
статический член или функцию-член, не являющуюся подстановкой, будет обозначать
один и тот же класс. Имена определяемых типов (typedef $$R.7.13), элементы
перечисления ($$R.7.2) или имена шаблонов типа ($$R.14) не имеют внешнего
связывания. Статические члены класса ($$R.9.4) допускают внешнее связывание.
Функции-члены, не являющиеся подстановкой, допускают внешнее связывание.
Функции-члены, являющиеся подстановкой, должны иметь в точности одно
определение в программе. Локальные имена ($$R.3.2), явно описанные со
спецификацией extern, имеют внешнее связывание, если только они уже не были
описаны как static ($$R.7.1.1). Типы, используемые во всех описаниях некоторого
внешнего имени, должны совпадать, за исключением использования имен
определяемых типов ($$R.7.1.3) и указания границ массивов ($$R.8.2.4). Должно быть
в точности одно определение для каждой функции, объекта, класса и элемента
перечисления, используемых в программе. Однако, если функция никогда не
вызывается и ее адрес никогда не используется, ее не нужно определять. Аналогично,
если имя класса используется только таким образом, что не требуется знать
определение класса, то класс не нужно определять. Область видимости функции