tmp/tmpk94b6dqj/{from.md → to.md}
RENAMED
|
@@ -2,11 +2,10 @@
|
|
| 2 |
|
| 3 |
The storage class specifiers are
|
| 4 |
|
| 5 |
``` bnf
|
| 6 |
storage-class-specifier:
|
| 7 |
-
'register'
|
| 8 |
'static'
|
| 9 |
'thread_local'
|
| 10 |
'extern'
|
| 11 |
'mutable'
|
| 12 |
```
|
|
@@ -15,70 +14,68 @@ At most one *storage-class-specifier* shall appear in a given
|
|
| 15 |
*decl-specifier-seq*, except that `thread_local` may appear with
|
| 16 |
`static` or `extern`. If `thread_local` appears in any declaration of a
|
| 17 |
variable it shall be present in all declarations of that entity. If a
|
| 18 |
*storage-class-specifier* appears in a *decl-specifier-seq*, there can
|
| 19 |
be no `typedef` specifier in the same *decl-specifier-seq* and the
|
| 20 |
-
*init-declarator-list* of the declaration
|
| 21 |
-
an anonymous union declared in a named
|
| 22 |
-
namespace, which shall be declared `static` (
|
| 23 |
-
*storage-class-specifier* applies to the
|
| 24 |
-
*init-declarator* in the list and not to any names
|
| 25 |
-
specifiers. A *storage-class-specifier*
|
| 26 |
-
|
| 27 |
-
instantiation ([[temp.explicit]])
|
|
|
|
| 28 |
|
| 29 |
-
|
| 30 |
-
declared
|
| 31 |
-
[[
|
| 32 |
-
storage duration ([[basic.stc.auto]]). A variable declared without a
|
| 33 |
-
*storage-class-specifier* at block scope or declared as a function
|
| 34 |
-
parameter has automatic storage duration by default.
|
| 35 |
-
|
| 36 |
-
A `register` specifier is a hint to the implementation that the variable
|
| 37 |
-
so declared will be heavily used. The hint can be ignored and in most
|
| 38 |
-
implementations it will be ignored if the address of the variable is
|
| 39 |
-
taken. This use is deprecated (see [[depr.register]]).
|
| 40 |
|
| 41 |
The `thread_local` specifier indicates that the named entity has thread
|
| 42 |
storage duration ([[basic.stc.thread]]). It shall be applied only to
|
| 43 |
the names of variables of namespace or block scope and to the names of
|
| 44 |
static data members. When `thread_local` is applied to a variable of
|
| 45 |
block scope the *storage-class-specifier* `static` is implied if no
|
| 46 |
other *storage-class-specifier* appears in the *decl-specifier-seq*.
|
| 47 |
|
| 48 |
The `static` specifier can be applied only to names of variables and
|
| 49 |
-
functions and to anonymous unions ([[class.union]]). There can be
|
| 50 |
-
`static` function declarations within a block, nor any `static`
|
| 51 |
-
parameters. A `static` specifier used in the declaration of a
|
| 52 |
-
declares the variable to have static storage duration (
|
| 53 |
[[basic.stc.static]]), unless accompanied by the `thread_local`
|
| 54 |
specifier, which declares the variable to have thread storage duration (
|
| 55 |
[[basic.stc.thread]]). A `static` specifier can be used in declarations
|
| 56 |
of class members; [[class.static]] describes its effect. For the
|
| 57 |
linkage of a name declared with a `static` specifier, see
|
| 58 |
[[basic.link]].
|
| 59 |
|
| 60 |
The `extern` specifier can be applied only to the names of variables and
|
| 61 |
functions. The `extern` specifier cannot be used in the declaration of
|
| 62 |
class members or function parameters. For the linkage of a name declared
|
| 63 |
-
with an `extern` specifier, see [[basic.link]].
|
| 64 |
-
|
|
|
|
|
|
|
|
|
|
| 65 |
|
| 66 |
The linkages implied by successive declarations for a given entity shall
|
| 67 |
agree. That is, within a given scope, each declaration declaring the
|
| 68 |
same variable name or the same overloading of a function name shall
|
| 69 |
imply the same linkage. Each function in a given set of overloaded
|
| 70 |
functions can have a different linkage, however.
|
| 71 |
|
|
|
|
|
|
|
| 72 |
``` cpp
|
| 73 |
static char* f(); // f() has internal linkage
|
| 74 |
char* f() // f() still has internal linkage
|
| 75 |
-
{
|
| 76 |
|
| 77 |
char* g(); // g() has external linkage
|
| 78 |
static char* g() // error: inconsistent linkage
|
| 79 |
-
{
|
| 80 |
|
| 81 |
void h();
|
| 82 |
inline void h(); // external linkage
|
| 83 |
|
| 84 |
inline void l();
|
|
@@ -101,14 +98,18 @@ static int c; // error: inconsistent linkage
|
|
| 101 |
|
| 102 |
extern int d; // d has external linkage
|
| 103 |
static int d; // error: inconsistent linkage
|
| 104 |
```
|
| 105 |
|
|
|
|
|
|
|
| 106 |
The name of a declared but undefined class can be used in an `extern`
|
| 107 |
declaration. Such a declaration can only be used in ways that do not
|
| 108 |
require a complete class type.
|
| 109 |
|
|
|
|
|
|
|
| 110 |
``` cpp
|
| 111 |
struct S;
|
| 112 |
extern S a;
|
| 113 |
extern S f();
|
| 114 |
extern void g(S);
|
|
@@ -117,21 +118,27 @@ void h() {
|
|
| 117 |
g(a); // error: S is incomplete
|
| 118 |
f(); // error: S is incomplete
|
| 119 |
}
|
| 120 |
```
|
| 121 |
|
| 122 |
-
|
| 123 |
-
|
| 124 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 125 |
|
| 126 |
``` cpp
|
| 127 |
class X {
|
| 128 |
mutable const int* p; // OK
|
| 129 |
mutable int* const q; // ill-formed
|
| 130 |
};
|
| 131 |
```
|
| 132 |
|
|
|
|
|
|
|
| 133 |
The `mutable` specifier on a class data member nullifies a `const`
|
| 134 |
specifier applied to the containing class object and permits
|
| 135 |
modification of the mutable class member even though the rest of the
|
| 136 |
object is `const` ([[dcl.type.cv]]).
|
| 137 |
|
|
|
|
| 2 |
|
| 3 |
The storage class specifiers are
|
| 4 |
|
| 5 |
``` bnf
|
| 6 |
storage-class-specifier:
|
|
|
|
| 7 |
'static'
|
| 8 |
'thread_local'
|
| 9 |
'extern'
|
| 10 |
'mutable'
|
| 11 |
```
|
|
|
|
| 14 |
*decl-specifier-seq*, except that `thread_local` may appear with
|
| 15 |
`static` or `extern`. If `thread_local` appears in any declaration of a
|
| 16 |
variable it shall be present in all declarations of that entity. If a
|
| 17 |
*storage-class-specifier* appears in a *decl-specifier-seq*, there can
|
| 18 |
be no `typedef` specifier in the same *decl-specifier-seq* and the
|
| 19 |
+
*init-declarator-list* or *member-declarator-list* of the declaration
|
| 20 |
+
shall not be empty (except for an anonymous union declared in a named
|
| 21 |
+
namespace or in the global namespace, which shall be declared `static` (
|
| 22 |
+
[[class.union.anon]])). The *storage-class-specifier* applies to the
|
| 23 |
+
name declared by each *init-declarator* in the list and not to any names
|
| 24 |
+
declared by other specifiers. A *storage-class-specifier* other than
|
| 25 |
+
`thread_local` shall not be specified in an explicit specialization (
|
| 26 |
+
[[temp.expl.spec]]) or an explicit instantiation ([[temp.explicit]])
|
| 27 |
+
directive.
|
| 28 |
|
| 29 |
+
[*Note 1*: A variable declared without a *storage-class-specifier* at
|
| 30 |
+
block scope or declared as a function parameter has automatic storage
|
| 31 |
+
duration by default ([[basic.stc.auto]]). — *end note*]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 32 |
|
| 33 |
The `thread_local` specifier indicates that the named entity has thread
|
| 34 |
storage duration ([[basic.stc.thread]]). It shall be applied only to
|
| 35 |
the names of variables of namespace or block scope and to the names of
|
| 36 |
static data members. When `thread_local` is applied to a variable of
|
| 37 |
block scope the *storage-class-specifier* `static` is implied if no
|
| 38 |
other *storage-class-specifier* appears in the *decl-specifier-seq*.
|
| 39 |
|
| 40 |
The `static` specifier can be applied only to names of variables and
|
| 41 |
+
functions and to anonymous unions ([[class.union.anon]]). There can be
|
| 42 |
+
no `static` function declarations within a block, nor any `static`
|
| 43 |
+
function parameters. A `static` specifier used in the declaration of a
|
| 44 |
+
variable declares the variable to have static storage duration (
|
| 45 |
[[basic.stc.static]]), unless accompanied by the `thread_local`
|
| 46 |
specifier, which declares the variable to have thread storage duration (
|
| 47 |
[[basic.stc.thread]]). A `static` specifier can be used in declarations
|
| 48 |
of class members; [[class.static]] describes its effect. For the
|
| 49 |
linkage of a name declared with a `static` specifier, see
|
| 50 |
[[basic.link]].
|
| 51 |
|
| 52 |
The `extern` specifier can be applied only to the names of variables and
|
| 53 |
functions. The `extern` specifier cannot be used in the declaration of
|
| 54 |
class members or function parameters. For the linkage of a name declared
|
| 55 |
+
with an `extern` specifier, see [[basic.link]].
|
| 56 |
+
|
| 57 |
+
[*Note 2*: The `extern` keyword can also be used in
|
| 58 |
+
*explicit-instantiation*s and *linkage-specification*s, but it is not a
|
| 59 |
+
*storage-class-specifier* in such contexts. — *end note*]
|
| 60 |
|
| 61 |
The linkages implied by successive declarations for a given entity shall
|
| 62 |
agree. That is, within a given scope, each declaration declaring the
|
| 63 |
same variable name or the same overloading of a function name shall
|
| 64 |
imply the same linkage. Each function in a given set of overloaded
|
| 65 |
functions can have a different linkage, however.
|
| 66 |
|
| 67 |
+
[*Example 1*:
|
| 68 |
+
|
| 69 |
``` cpp
|
| 70 |
static char* f(); // f() has internal linkage
|
| 71 |
char* f() // f() still has internal linkage
|
| 72 |
+
{ ... }
|
| 73 |
|
| 74 |
char* g(); // g() has external linkage
|
| 75 |
static char* g() // error: inconsistent linkage
|
| 76 |
+
{ ... }
|
| 77 |
|
| 78 |
void h();
|
| 79 |
inline void h(); // external linkage
|
| 80 |
|
| 81 |
inline void l();
|
|
|
|
| 98 |
|
| 99 |
extern int d; // d has external linkage
|
| 100 |
static int d; // error: inconsistent linkage
|
| 101 |
```
|
| 102 |
|
| 103 |
+
— *end example*]
|
| 104 |
+
|
| 105 |
The name of a declared but undefined class can be used in an `extern`
|
| 106 |
declaration. Such a declaration can only be used in ways that do not
|
| 107 |
require a complete class type.
|
| 108 |
|
| 109 |
+
[*Example 2*:
|
| 110 |
+
|
| 111 |
``` cpp
|
| 112 |
struct S;
|
| 113 |
extern S a;
|
| 114 |
extern S f();
|
| 115 |
extern void g(S);
|
|
|
|
| 118 |
g(a); // error: S is incomplete
|
| 119 |
f(); // error: S is incomplete
|
| 120 |
}
|
| 121 |
```
|
| 122 |
|
| 123 |
+
— *end example*]
|
| 124 |
+
|
| 125 |
+
The `mutable` specifier shall appear only in the declaration of a
|
| 126 |
+
non-static data member ([[class.mem]]) whose type is neither
|
| 127 |
+
const-qualified nor a reference type.
|
| 128 |
+
|
| 129 |
+
[*Example 3*:
|
| 130 |
|
| 131 |
``` cpp
|
| 132 |
class X {
|
| 133 |
mutable const int* p; // OK
|
| 134 |
mutable int* const q; // ill-formed
|
| 135 |
};
|
| 136 |
```
|
| 137 |
|
| 138 |
+
— *end example*]
|
| 139 |
+
|
| 140 |
The `mutable` specifier on a class data member nullifies a `const`
|
| 141 |
specifier applied to the containing class object and permits
|
| 142 |
modification of the mutable class member even though the rest of the
|
| 143 |
object is `const` ([[dcl.type.cv]]).
|
| 144 |
|