{
float r=10; // класс памяти – auto, размещается в стеке, продолжительность –
// с точки объявления до конца блока
char * ptr=malloc(10); // класс памяти – heap, указывает на область памяти
// heap, продолжительность – с точки объявления
// до конца блока
…
free(ptr);
}
Видимостью идентификатора называется область исходного кода программы, из которого допустим нормальный доступ к связанному с идентификатором объекту. Обычно контекст и видимость совпадают, однако бывают случаи, когда объект временно скрыт вследствие наличия идентификатора с тем же именем. Объект при этом не прекращает своего существования, но исходный идентификатор не может служить для доступа к нему до тех пор, пока не закончится контекст дублирующего идентификатора.
Видимость не может выходить за пределы контекста; но контекст может превышать видимость. Например:
{
int i; char ch; // автоматическое распределение по умолчанию
i = 3; // объекты int i и char ch в контексте и видимы
...
{
double i; // объект double i в контексте и видим
i = 2.0e3; // объект int i в контексте, но скрыт
|
|
ch = 'A'; // объект char ch в контексте и видим
} // объект double i вне контекста
i += 1; // объект int i видим и равен 4
... // объект char ch в контексте, видим и равен 'A'
}
... // int i и char ch вне контекста
Выполняемая программа обычно создается компиляцией нескольких независимых единиц трансляции, а затем компоновкой получившихся объектных файлов с уже существующими библиотеками. Проблема возникает, когда один и тот же идентификатор объявлен в разных контекстах (например, в различных файлах), либо объявлен более одного раза в одном и том же контексте.
Компоновка – это процесс, который позволяет правильно связать каждое вхождение идентификатора с одним конкретным объектом или функцией. Все идентификаторы имеют один из трех атрибутов компоновки, тесно связанных с их контекстом: внешнюю компоновку, внутреннюю компоновку или отсутствие компоновки. Эти атрибуты определяются местоположением и форматом объявлений, вместе с явным (или неявным по умолчанию) использованием спецификатора класса памяти static или extern.