tmp/tmp4x5yq2d_/{from.md → to.md}
RENAMED
|
@@ -1,32 +1,43 @@
|
|
| 1 |
-
#### The *cv-
|
| 2 |
|
| 3 |
-
There are two *cv-
|
| 4 |
*cv-qualifier* shall appear at most once in a *cv-qualifier-seq*. If a
|
| 5 |
*cv-qualifier* appears in a *decl-specifier-seq*, the
|
| 6 |
-
*init-declarator-list* of the declaration
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 16 |
|
| 17 |
A pointer or reference to a cv-qualified type need not actually point or
|
| 18 |
refer to a cv-qualified object, but it is treated as if it does; a
|
| 19 |
const-qualified access path cannot be used to modify an object even if
|
| 20 |
the object referenced is a non-const object and can be modified through
|
| 21 |
-
some other access path.
|
| 22 |
-
|
|
|
|
|
|
|
|
|
|
| 23 |
|
| 24 |
Except that any class member declared `mutable` ([[dcl.stc]]) can be
|
| 25 |
modified, any attempt to modify a `const` object during its lifetime (
|
| 26 |
[[basic.life]]) results in undefined behavior.
|
| 27 |
|
|
|
|
|
|
|
| 28 |
``` cpp
|
| 29 |
const int ci = 3; // cv-qualified (initialized as required)
|
| 30 |
ci = 4; // ill-formed: attempt to modify const
|
| 31 |
|
| 32 |
int i = 2; // not cv-qualified
|
|
@@ -41,11 +52,11 @@ ip = const_cast<int*>(cip); // cast needed to convert const int* to int*
|
|
| 41 |
const int* ciq = new const int (3); // initialized as required
|
| 42 |
int* iq = const_cast<int*>(ciq); // cast required
|
| 43 |
*iq = 4; // undefined: modifies a const object
|
| 44 |
```
|
| 45 |
|
| 46 |
-
For another example
|
| 47 |
|
| 48 |
``` cpp
|
| 49 |
struct X {
|
| 50 |
mutable int i;
|
| 51 |
int j;
|
|
@@ -61,18 +72,21 @@ y.x.j++; // ill-formed: const-qualified member modified
|
|
| 61 |
Y* p = const_cast<Y*>(&y); // cast away const-ness of y
|
| 62 |
p->x.i = 99; // well-formed: mutable member can be modified
|
| 63 |
p->x.j = 99; // undefined: modifies a const member
|
| 64 |
```
|
| 65 |
|
| 66 |
-
|
| 67 |
-
is implementation-defined. If an attempt is made to refer to an object
|
| 68 |
-
defined with a volatile-qualified type through the use of a glvalue with
|
| 69 |
-
a non-volatile-qualified type, the program behavior is undefined.
|
| 70 |
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 78 |
|
|
|
|
| 1 |
+
#### The *cv-qualifier*s <a id="dcl.type.cv">[[dcl.type.cv]]</a>
|
| 2 |
|
| 3 |
+
There are two *cv-qualifier*s, `const` and `volatile`. Each
|
| 4 |
*cv-qualifier* shall appear at most once in a *cv-qualifier-seq*. If a
|
| 5 |
*cv-qualifier* appears in a *decl-specifier-seq*, the
|
| 6 |
+
*init-declarator-list* or *member-declarator-list* of the declaration
|
| 7 |
+
shall not be empty.
|
| 8 |
+
|
| 9 |
+
[*Note 1*: [[basic.type.qualifier]] and [[dcl.fct]] describe how
|
| 10 |
+
cv-qualifiers affect object and function types. — *end note*]
|
| 11 |
+
|
| 12 |
+
Redundant cv-qualifications are ignored.
|
| 13 |
+
|
| 14 |
+
[*Note 2*: For example, these could be introduced by
|
| 15 |
+
typedefs. — *end note*]
|
| 16 |
+
|
| 17 |
+
[*Note 3*: Declaring a variable `const` can affect its linkage (
|
| 18 |
+
[[dcl.stc]]) and its usability in constant expressions (
|
| 19 |
+
[[expr.const]]). As described in [[dcl.init]], the definition of an
|
| 20 |
+
object or subobject of const-qualified type must specify an initializer
|
| 21 |
+
or be subject to default-initialization. — *end note*]
|
| 22 |
|
| 23 |
A pointer or reference to a cv-qualified type need not actually point or
|
| 24 |
refer to a cv-qualified object, but it is treated as if it does; a
|
| 25 |
const-qualified access path cannot be used to modify an object even if
|
| 26 |
the object referenced is a non-const object and can be modified through
|
| 27 |
+
some other access path.
|
| 28 |
+
|
| 29 |
+
[*Note 4*: Cv-qualifiers are supported by the type system so that they
|
| 30 |
+
cannot be subverted without casting (
|
| 31 |
+
[[expr.const.cast]]). — *end note*]
|
| 32 |
|
| 33 |
Except that any class member declared `mutable` ([[dcl.stc]]) can be
|
| 34 |
modified, any attempt to modify a `const` object during its lifetime (
|
| 35 |
[[basic.life]]) results in undefined behavior.
|
| 36 |
|
| 37 |
+
[*Example 1*:
|
| 38 |
+
|
| 39 |
``` cpp
|
| 40 |
const int ci = 3; // cv-qualified (initialized as required)
|
| 41 |
ci = 4; // ill-formed: attempt to modify const
|
| 42 |
|
| 43 |
int i = 2; // not cv-qualified
|
|
|
|
| 52 |
const int* ciq = new const int (3); // initialized as required
|
| 53 |
int* iq = const_cast<int*>(ciq); // cast required
|
| 54 |
*iq = 4; // undefined: modifies a const object
|
| 55 |
```
|
| 56 |
|
| 57 |
+
For another example,
|
| 58 |
|
| 59 |
``` cpp
|
| 60 |
struct X {
|
| 61 |
mutable int i;
|
| 62 |
int j;
|
|
|
|
| 72 |
Y* p = const_cast<Y*>(&y); // cast away const-ness of y
|
| 73 |
p->x.i = 99; // well-formed: mutable member can be modified
|
| 74 |
p->x.j = 99; // undefined: modifies a const member
|
| 75 |
```
|
| 76 |
|
| 77 |
+
— *end example*]
|
|
|
|
|
|
|
|
|
|
| 78 |
|
| 79 |
+
The semantics of an access through a volatile glvalue are
|
| 80 |
+
*implementation-defined*. If an attempt is made to access an object
|
| 81 |
+
defined with a volatile-qualified type through the use of a non-volatile
|
| 82 |
+
glvalue, the behavior is undefined.
|
| 83 |
+
|
| 84 |
+
[*Note 5*: `volatile` is a hint to the implementation to avoid
|
| 85 |
+
aggressive optimization involving the object because the value of the
|
| 86 |
+
object might be changed by means undetectable by an implementation.
|
| 87 |
+
Furthermore, for some implementations, `volatile` might indicate that
|
| 88 |
+
special hardware instructions are required to access the object. See
|
| 89 |
+
[[intro.execution]] for detailed semantics. In general, the semantics of
|
| 90 |
+
`volatile` are intended to be the same in C++as they are in
|
| 91 |
+
C. — *end note*]
|
| 92 |
|