10 Declarations [dcl.dcl]

10.1 Specifiers [dcl.spec]

10.1.7 Type specifiers [dcl.type]

10.1.7.1 The cv-qualifiers [dcl.type.cv]

Их два cv-qualifiers, const и volatile. Каждый cv-qualifierдолжен появляться не более одного раза в cv-qualifier-seq. Если a cv-qualifierпоявляется в a decl-specifier-seq, то init-declarator-list или member-declarator-listдекларации не может быть пустым. [ Note: [basic.type.qualifier] и [dcl.fct] опишите, как cv-квалификаторы влияют на типы объектов и функций. ] Избыточные CV-квалификации игнорируются. [ Например, они могут быть введены с помощью typedefs. ]end noteNote: end note

[ Note: Объявление переменной const может повлиять на ее linkage ([dcl.stc]) и удобство использования в constant expressions. Как описано в [dcl.init], определение объекта или подобъекта типа с указанием const должно указывать инициализатор или подвергаться инициализации по умолчанию. ]end note

Указатель или ссылка на cv-квалифицированный тип не обязательно должны указывать или ссылаться на cv-квалифицированный объект, но он обрабатывается так, как если бы он это делал; Путь доступа с указанием констант не может использоваться для изменения объекта, даже если указанный объект не является константным объектом и может быть изменен с помощью другого пути доступа. [ Note: Cv-квалификаторы поддерживаются системой типов, так что без них их нельзя ниспровергнуть casting. ]end note

За исключением того, что любой объявленный член класса mutable может быть изменен, любая попытка изменить const объект во время его выполнения lifetime приводит к неопределенному поведению. [Example:

const int ci = 3;                       // cv-qualified (initialized as required)
ci = 4;                                 // ill-formed: attempt to modify const

int i = 2;                              // not cv-qualified
const int* cip;                         // pointer to const int
cip = &i;                               // OK: cv-qualified access path to unqualified
*cip = 4;                               // ill-formed: attempt to modify through ptr to const

int* ip;
ip = const_cast<int*>(cip);             // cast needed to convert const int* to int*
*ip = 4;                                // defined: *ip points to i, a non-const object

const int* ciq = new const int (3);     // initialized as required
int* iq = const_cast<int*>(ciq);        // cast required
*iq = 4;                                // undefined: modifies a const object

Другой пример:

struct X {
  mutable int i;
  int j;
};
struct Y {
  X x;
  Y();
};

const Y y;
y.x.i++;                                // well-formed: mutable member can be modified
y.x.j++;                                // ill-formed: const-qualified member modified
Y* p = const_cast<Y*>(&y);              // cast away const-ness of y
p->x.i = 99;                            // well-formed: mutable member can be modified
p->x.j = 99;                            // undefined: modifies a const member

end example]

Семантика доступа через изменчивое значение glvalue определяется реализацией. Если предпринята попытка доступа к объекту, определенному с типом с изменяемым атрибутом, с помощью энергонезависимого значения glvalue, поведение не определено.

[ Note: volatile является подсказкой реализации, чтобы избежать агрессивной оптимизации, связанной с объектом, потому что значение объекта может быть изменено средствами, не обнаруживаемыми реализацией. Кроме того, для некоторых реализаций volatile может указывать на то, что для доступа к объекту требуются специальные аппаратные инструкции. См. [intro.execution] Подробную семантику. В общем, семантика volatile в C ++ должна быть такой же, как и в C. ]end note