Kernighan, B. W. and Ritchie, D. M. "The 'C' Programming Language"; Chapter 20

20. Правила, определяющие область действия.

Вся C-программа необязательно компилируется одновременно; исходныйтекст программы может храниться в нескольких файлах и ранеескомпилированные процедуры могут загружаться из библиотек. Связьмежду функциями может осуществляться как через явные обращения, таки в результате манипулирования с внешними данными.

Поэтому следует рассмотреть два вида областей действия: во-первых,ту, которая может быть названа лексической областью действияидентификатора и которая по существу является той областью в программе,где этот идентификатор можно использовать, не вызывая диагностическогосообщения "неопределенный идентификатор"; и во-вторых, область действия,которая связана с внешними идентификаторами и которая характеризуетсяправилом, что ссылки на один и тот же внешний идентификатор являютсяссылками на один и тот же об'ект.

Содержание

20.1. Лексическая область действия.
20.2. Область действия внешних идентификаторов.


20.1. Лексическая область действия.

Лексическая область действия идентификаторов, описанных во внешнихопределениях, простирается от определения до конца исходного файла,в котором он находится. Лексическая область действия идентификаторов,являющихся формальными параметрами, распространяется на ту функцию, ккоторой они относятся. Лексическая область действия идентификаторов,описанных в начале блока, простирается до конца этого блока.Лексической областью действия меток является та функция, в которой онинаходятся.

Поскольку все обращения на один и тот же внешний идентификаторобращаются к одному и тому же об'екту (см. п. 20.2), компиляторпроверяет все описания одного и того же внешнего идентификатора насовместимость; в действительности их область действия распространяетсяна весь файл, в котором они находятся.

Во всех случаях, однако, есть некоторый идентификатор, явным образомописан в начале блока, включая и блок, который образует функцию, тодействие любого описания этого идентификатора вне блокаприостанавливается до конца этого блока.

Напомним также (п. 17.5), что идентификаторы, соответствующие обычнымпеременным, с одной стороны, и идентификаторы, соответствующие членами ярлыкам структур и об'единений, с другой стороны, формируют дванепересекающихся класса, которые не вступают в противоречие. Члены иярлыки подчиняются тем же самым правилам определения областейдействия, как и другие идентификаторы. Имена, специфицируемые спомощью typedef, входят в тот же класс, что и обычные идентификаторы.Они могут быть переопределены во внутренних блоках, но во внутреннемописании тип должен быть указан явно:

 typedef float distance; ... {        auto int distance; ...
Во втором описании спецификатор типа int должен присутствовать, таккак в противном случае это описание будет принято за описание безописателей с типом distance (прим. Автора: согласитесь, что лед здесьтонок.).


20.2. Область действия внешних идентификаторов.

Если функция ссылается на идентификатор, описанный как extern, тогдe-то среди файлов или библиотек, образующих полную программу, должносодержаться внешнее определение этого идентификатора. Все функции даннойпрограммы, которые ссылаются на один и тот же внешний идентификатор,ссылаются на один и тот же об'ект, так что следует позаботиться, чтобыспецифицированные в этом определении тип и размер были совместимы стипом и размером, указываемыми в каждой функции, которая ссылается наэти данные.

Появление ключевого слова extern во внешнем определении указывает нато, что память для описанных в нем идентификаторов будет выделена вдругом файле. Следовательно, в состоящей из многих файлов программевнешнее определение идентификатора, не содержащее спецификатора extern,должно появляться ровно в одном из этих файлов. Любые другие файлы,которые желают дать внешнее определение этого идентификатора, должнывключать в это определение слово extern. Идентификатор может бытьинициализирован только в том описании, которое приводит к выделениюпамяти.

Идентификаторы, внешнее определение которых начинается со слова static,недоступны из других файлов. Функции могут быть описаны как static.