A.4 const |
Предыдущая Содержание Следующая |
const является классификатором, указывающим, что компилятор не должен допускать присвоения. Это довольно сильно отличается от действительно постоянных значений. Допускается инициализация; локальные переменные с const могут даже быть проинициализированы с помощью значений переменных:
int x = 10; int f () { const int xsave = x; ... }
Всегда можно использовать операции явного приведения типов для обхода проверок компилятора:
const int cx = 10; (int) cx = 20; ошибка * (int *) & cx = 20; не запрещено
Эти преобразования иногда необходимы при присвоении значений указателя:
const void * vp;
int * ip; int * const p = ip; ок для локальных переменных
vp = ip; ок, присвоение блокируется ip = vp; ошибка, разрешает присвоение ip = (void *) vp; ок, грубая сила * (const int **) & ip = vp; ок, избыточно p = ip; ошибка, указатель заблокирован * p = 10; ок, цель не заблокирована
const обычно связывается с левой частью; однако, const может быть указан перед именем типа в декларации:
int const v [10]; десять постоянных элементов const int * const cp = v; постоянный указатель на постоянное значение
const используется для указания того, что нежелательно изменять значение после инициализации или из функции:
char * strcpy (char * target, const char * source);
Компилятор может поместить глобальные объекты в защищенный от записи сегмент, если они были защищены const целиком. Это означает, например, что компоненты структуры наследуют const:
const struct { int i; } c; c.i = 10; ошибка
Это также исключает динамическую инициализацию следующего указателя:
void * const String;
Не ясно, может ли функция создавать результат с const. ANSI-C не позволяет это. GNU-C предполагает, что в этом случае функция не вызывает никаких побочных эффектов и смотрит только на её аргументы, но ни на глобальные переменные, ни на значения после указателей. Вызовы функции такого вида могут быть удалены в процессе обычного отсева подвыражений в процессе компиляции. Поскольку значения указателей на объекты с const не могут быть присвоены незащищённым указателям, ANSI-C имеет странную декларацию для bsearch():
void * bsearch (const void * key, const void * table, size_t nel, size_t width, int (* cmp) (const void * key, const void * elt));
table[] импортируется с const, то есть её элементы не могут быть изменены и постоянная таблица может быть передана в качестве аргумента. Тем не менее, результат bsearch() указывает на элемент таблицы и не защищает его от модификации. Как правило, если объекты не будут изменяться через указатели, параметрами функции должны быть указатели на объекты именно с const. То же самое относится и к переменным указателей. Результат функции (почти) никогда не должен включать в себя const.
|
Предыдущая Содержание Следующая |