Стандарт C++ 98 (1119566), страница 34
Текст из файла (страница 34)
The inlinespecifier indicates to the implementation that inline substitution of the function body at the point of call isto be preferred to the usual function call mechanism. An implementation is not required to perform thisinline substitution at the point of call; however, even if this inline substitution is omitted, the other rules for104© ISO/IECISO/IEC 14882:1998(E)7 Declarations7.1.2 Function specifiersinline functions defined by 7.1.2 shall still be respected.3A function defined within a class definition is an inline function. The inline specifier shall not appearon a block scope function declaration.79)4An inline function shall be defined in every translation unit in which it is used and shall have exactly thesame definition in every case (3.2). [Note: a call to the inline function may be encountered before its definition appears in the translation unit.
] If a function with external linkage is declared inline in one translation unit, it shall be declared inline in all translation units in which it appears; no diagnostic is required. Aninline function with external linkage shall have the same address in all translation units. A staticlocal variable in an extern inline function always refers to the same object. A string literal in anextern inline function is the same object in different translation units.5The virtual specifier shall only be used in declarations of nonstatic class member functions that appearwithin a member-specification of a class declaration; see 10.3.6The explicit specifier shall be used only in declarations of constructors within a class declaration; see12.3.1.7.1.3 The typedef specifier1[dcl.typedef]Declarations containing the decl-specifier typedef declare identifiers that can be used later for namingfundamental (3.9.1) or compound (3.9.2) types.
The typedef specifier shall not be used in a functiondefinition (8.4), and it shall not be combined in a decl-specifier-seq with any other kind of specifier excepta type-specifier.typedef-name:identifierA name declared with the typedef specifier becomes a typedef-name. Within the scope of its declaration,a typedef-name is syntactically equivalent to a keyword and names the type associated with the identifier inthe way described in clause 8.
A typedef-name is thus a synonym for another type. A typedef-name doesnot introduce a new type the way a class declaration (9.1) or enum declaration does. [Example: aftertypedef int MILES, *KLICKSP;the constructionsMILES distance;extern KLICKSP metricp;are all correct declarations; the type of distance is int; that of metricp is “pointer to int.” ]2In a given scope, a typedef specifier can be used to redefine the name of any type declared in that scopeto refer to the type to which it already refers. [Example:typedeftypedeftypedeftypedefstruct s { /* ... */ } s;int I;int I;I I;—end example]3In a given scope, a typedef specifier shall not be used to redefine the name of any type declared in thatscope to refer to a different type. [Example:class complex { /* ... */ };typedef int complex;// error: redefinition—end example] Similarly, in a given scope, a class or enumeration shall not be declared with the samename as a typedef-name that is declared in that scope and refers to a type other than the class or enumeration itself.
[Example:__________________79) The inline keyword has no effect on the linkage of a function.105ISO/IEC 14882:1998(E)© ISO/IEC7.1.3 The typedef specifiertypedef int complex;class complex { /* ... */ };7 Declarations// error: redefinition—end example]4A typedef-name that names a class is a class-name (9.1).
If a typedef-name is used following the class-keyin an elaborated-type-specifier (7.1.5.3) or in the class-head of a class declaration (9), or is used as theidentifier in the declarator for a constructor or destructor declaration (12.1, 12.4), the program is ill-formed.[Example:struct S {S();~S();};typedef struct S T;S a = T();struct T * p;// OK// error—end example]5If the typedef declaration defines an unnamed class (or enum), the first typedef-name declared by the declaration to be that class type (or enum type) is used to denote the class type (or enum type) for linkage purposes only (3.5).
[Example:typedef struct { } *ps, S;// S is the class name for linkage purposes—end example] [Note: if the typedef-name is used where a class-name (or enum-name) is required, theprogram is ill-formed. For example,typedef struct {S();// error: requires a return type because S is// an ordinary member function, not a constructor} S;—end note]7.1.4 The friend specifier1The friend specifier is used to specify access to class members; see 11.4.7.1.5 Type specifiers1[dcl.friend][dcl.type]The type-specifiers aretype-specifier:simple-type-specifierclass-specifierenum-specifierelaborated-type-specifiercv-qualifierAs a general rule, at most one type-specifier is allowed in the complete decl-specifier-seq of a declaration.The only exceptions to this rule are the following:— const or volatile can be combined with any other type-specifier.
However, redundant cvqualifiers are prohibited except when introduced through the use of typedefs (7.1.3) or template typearguments (14.3), in which case the redundant cv-qualifiers are ignored.— signed or unsigned can be combined with char, long, short, or int.— short or long can be combined with int.— long can be combined with double.106© ISO/IECISO/IEC 14882:1998(E)7 Declarations7.1.5 Type specifiers2At least one type-specifier that is not a cv-qualifier is required in a declaration unless it declares a constructor, destructor or conversion function.80)3[Note: class-specifiers and enum-specifiers are discussed in clause 9 and 7.2, respectively. The remainingtype-specifiers are discussed in the rest of this section.
]7.1.5.1 The cv-qualifiers[dcl.type.cv]1There are two cv-qualifiers, const and volatile. If a cv-qualifier appears in a decl-specifier-seq, theinit-declarator-list of the declaration shall not be empty. [Note: 3.9.3 describes how cv-qualifiers affectobject and function types. ]2An object declared in namespace scope with a const-qualified type has internal linkage unless it is explicitly declared extern or unless it was previously declared to have external linkage.
A variable of constqualified integral or enumeration type initialized by an integral constant expression can be used in integralconstant expressions (5.19). [Note: as described in 8.5, the definition of an object or subobject of constqualified type must specify an initializer or be subject to default-initialization. ]3A pointer or reference to a cv-qualified type need not actually point or refer to a cv-qualified object, but it istreated as if it does; a const-qualified access path cannot be used to modify an object even if the object referenced is a non-const object and can be modified through some other access path.
[Note: cv-qualifiers aresupported by the type system so that they cannot be subverted without casting (5.2.11). ]4Except that any class member declared mutable (7.1.1) can be modified, any attempt to modify a constobject during its lifetime (3.8) results in undefined behavior.5[Example:const int ci = 3;ci = 4;// cv-qualified (initialized as required)// ill-formed: attempt to modify constint i = 2;const int* cip;cip = &i;*cip = 4;// not cv-qualified// pointer to const int// OK: cv-qualified access path to unqualified// ill-formed: attempt to modify through ptr to constint* ip;ip = const_cast<int*>(cip);*ip = 4;// cast needed to convert const int* to int*// defined: *ip points to i, a non-const objectconst int* ciq = new const int (3);int* iq = const_cast<int*>(ciq);*iq = 4;6// initialized as required// cast required// undefined: modifies a const objectFor another exampleclass X {public:mutable int i;int j;};class Y {public:X x;Y();};__________________80) There is no special provision for a decl-specifier-seq that lacks a type-specifier or that has a type-specifier that only specifies cvqualifiers.
The “implicit int” rule of C is no longer supported.107ISO/IEC 14882:1998(E)© ISO/IEC7.1.5.1 The cv-qualifiersconst Y y;y.x.i++;y.x.j++;Y* p = const_cast<Y*>(&y);p->x.i = 99;p->x.j = 99;7 Declarations// well-formed: mutable member can be modified// ill-formed: const-qualified member modified// cast away const-ness of y// well-formed: mutable member can be modified// undefined: modifies a const member—end example]7If an attempt is made to refer to an object defined with a volatile-qualified type through the use of an lvaluewith a non-volatile-qualified type, the program behaviour is undefined.8[Note: volatile is a hint to the implementation to avoid aggressive optimization involving the objectbecause the value of the object might be changed by means undetectable by an implementation. See 1.9 fordetailed semantics.
In general, the semantics of volatile are intended to be the same in C++ as they arein C. ]7.1.5.2 Simple type specifiers1[dcl.type.simple]The simple type specifiers aresimple-type-specifier:::opt nested-name-specifieropt type-name::opt nested-name-specifier template template-idcharwchar_tboolshortintlongsignedunsignedfloatdoublevoidtype-name:class-nameenum-nametypedef-nameThe simple-type-specifiers specify either a previously-declared user-defined type or one of the fundamentaltypes (3.9.1).