Стандарт C++ 11 (1119564), страница 21
Текст из файла (страница 21)
An entity with external linkage declared using such a type could not correspond to anyother entity in another translation unit of the program and thus must be defined in the translation unit ifit is odr-used. Also note that classes with linkage may contain members whose types do not have linkage,and that typedef names are ignored in the determination of whether a type has linkage. — end note ][ Example:template <class T> struct B {void g(T) { }void h(T);friend void i(B, T) { }};void f() {struct A { int x; };A a = { 1 };B<A> ba;ba.g(a);ba.h(a);i(ba, a);}// no linkage////////declares B<A>::g(A) and B<A>::h(A)OKerror: B<A>::h(A) not defined in the translation unitOK— end example ]9Two names that are the same (Clause 3) and that are declared in different scopes shall denote the samevariable, function, type, enumerator, template or namespace if— both names have external linkage or else both names have internal linkage and are declared in thesame translation unit; and— both names refer to members of the same namespace or to members, not by inheritance, of the sameclass; and— when both names denote functions, the parameter-type-lists of the functions (8.3.5) are identical; and— when both names denote function templates, the signatures (14.5.6.1) are the same.10After all adjustments of types (during which typedefs (7.1.3) are replaced by their definitions), the typesspecified by all declarations referring to a given variable or function shall be identical, except that declarations for an array object can specify array types that differ by the presence or absence of a major arraybound (8.3.4).
A violation of this rule on type identity does not require a diagnostic.11[ Note: Linkage to non-C++ declarations can be achieved using a linkage-specification (7.5). — end note ]§ 3.5© ISO/IEC 2011 – All rights reserved61ISO/IEC 14882:2011(E)3.6Start and termination3.6.1[basic.start]Main function[basic.start.main]1A program shall contain a global function called main, which is the designated start of the program. Itis implementation-defined whether a program in a freestanding environment is required to define a mainfunction. [ Note: In a freestanding environment, start-up and termination is implementation-defined; startup contains the execution of constructors for objects of namespace scope with static storage duration;termination contains the execution of destructors for objects with static storage duration. — end note ]2An implementation shall not predefine the main function.
This function shall not be overloaded. It shallhave a return type of type int, but otherwise its type is implementation-defined. All implementations shallallow both of the following definitions of main:int main() { /* ...*/ }andint main(int argc, char* argv[]) { /* ...*/ }In the latter form argc shall be the number of arguments passed to the program from the environment in which the program is run. If argc is nonzero these arguments shall be supplied in argv[0]through argv[argc-1] as pointers to the initial characters of null-terminated multibyte strings (ntmbss) (17.5.2.1.4.2) and argv[0] shall be the pointer to the initial character of a ntmbs that represents thename used to invoke the program or "".
The value of argc shall be non-negative. The value of argv[argc]shall be 0. [ Note: It is recommended that any further (optional) parameters be added after argv. — endnote ]3The function main shall not be used within a program. The linkage (3.5) of main is implementation-defined.A program that defines main as deleted or that declares main to be inline, static, or constexpr is illformed.
The name main is not otherwise reserved. [ Example: member functions, classes, and enumerationscan be called main, as can entities in other namespaces. — end example ]4Terminating the program without leaving the current block (e.g., by calling the function std::exit(int)(18.5)) does not destroy any objects with automatic storage duration (12.4). If std::exit is called toend a program during the destruction of an object with static or thread storage duration, the program hasundefined behavior.5A return statement in main has the effect of leaving the main function (destroying any objects with automaticstorage duration) and calling std::exit with the return value as the argument. If control reaches the endof main without encountering a return statement, the effect is that of executingreturn 0;3.6.2Initialization of non-local variables[basic.start.init]1There are two broad classes of named non-local variables: those with static storage duration (3.7.1) andthose with thread storage duration (3.7.2).
Non-local variables with static storage duration are initializedas a consequence of program initiation. Non-local variables with thread storage duration are initialized as aconsequence of thread execution. Within each of these phases of initiation, initialization occurs as follows.2Variables with static storage duration (3.7.1) or thread storage duration (3.7.2) shall be zero-initialized (8.5)before any other initialization takes place.Constant initialization is performed:§ 3.6.262© ISO/IEC 2011 – All rights reservedISO/IEC 14882:2011(E)— if each full-expression (including implicit conversions) that appears in the initializer of a reference withstatic or thread storage duration is a constant expression (5.19) and the reference is bound to an lvaluedesignating an object with static storage duration or to a temporary (see 12.2);— if an object with static or thread storage duration is initialized by a constructor call, if the constructor isa constexpr constructor, if all constructor arguments are constant expressions (including conversions),and if, after function invocation substitution (7.1.5), every constructor call and full-expression inthe mem-initializers and in the brace-or-equal-initializers for non-static data members is a constantexpression;— if an object with static or thread storage duration is not initialized by a constructor call and if everyfull-expression that appears in its initializer is a constant expression.Together, zero-initialization and constant initialization are called static initialization; all other initialization isdynamic initialization.
Static initialization shall be performed before any dynamic initialization takes place.Dynamic initialization of a non-local variable with static storage duration is either ordered or unordered.Definitions of explicitly specialized class template static data members have ordered initialization.
Otherclass template static data members (i.e., implicitly or explicitly instantiated specializations) have unorderedinitialization. Other non-local variables with static storage duration have ordered initialization. Variableswith ordered initialization defined within a single translation unit shall be initialized in the order of theirdefinitions in the translation unit. If a program starts a thread (30.3), the subsequent initialization of avariable is unsequenced with respect to the initialization of a variable defined in a different translation unit.Otherwise, the initialization of a variable is indeterminately sequenced with respect to the initialization ofa variable defined in a different translation unit. If a program starts a thread, the subsequent unorderedinitialization of a variable is unsequenced with respect to every other dynamic initialization.
Otherwise,the unordered initialization of a variable is indeterminately sequenced with respect to every other dynamicinitialization. [ Note: This definition permits initialization of a sequence of ordered variables concurrentlywith another sequence. — end note ] [ Note: The initialization of local static variables is described in 6.7.— end note ]3An implementation is permitted to perform the initialization of a non-local variable with static storageduration as a static initialization even if such initialization is not required to be done statically, providedthat— the dynamic version of the initialization does not change the value of any other object of namespacescope prior to its initialization, and— the static version of the initialization produces the same value in the initialized variable as would beproduced by the dynamic initialization if all variables not required to be initialized statically wereinitialized dynamically.[ Note: As a consequence, if the initialization of an object obj1 refers to an object obj2 of namespace scopepotentially requiring dynamic initialization and defined later in the same translation unit, it is unspecifiedwhether the value of obj2 used will be the value of the fully initialized obj2 (because obj2 was staticallyinitialized) or will be the value of obj2 merely zero-initialized.
For example,inline double fd() { return 1.0; }extern double d1;double d2 = d1;// unspecified:// may be statically initialized to 0.0 or// dynamically initialized to 0.0 if d1 is// dynamically initialized, or 1.0 otherwisedouble d1 = fd();// may be initialized statically or dynamically to 1.0— end note ]§ 3.6.2© ISO/IEC 2011 – All rights reserved63ISO/IEC 14882:2011(E)4It is implementation-defined whether the dynamic initialization of a non-local variable with static storageduration is done before the first statement of main. If the initialization is deferred to some point in timeafter the first statement of main, it shall occur before the first odr-use (3.2) of any function or variabledefined in the same translation unit as the variable to be initialized.34 [ Example:// - File 1 #include "a.h"#include "b.h"B b;A::A(){b.Use();}// - File 2 #include "a.h"A a;// - File 3 #include "a.h"#include "b.h"extern A a;extern B b;int main() {a.Use();b.Use();}It is implementation-defined whether either a or b is initialized before main is entered or whether theinitializations are delayed until a is first odr-used in main.
In particular, if a is initialized before main isentered, it is not guaranteed that b will be initialized before it is odr-used by the initialization of a, that is,before A::A is called. If, however, a is initialized at some point after the first statement of main, b will beinitialized prior to its use in A::A. — end example ]5It is implementation-defined whether the dynamic initialization of a non-local variable with static or threadstorage duration is done before the first statement of the initial function of the thread. If the initializationis deferred to some point in time after the first statement of the initial function of the thread, it shall occurbefore the first odr-use (3.2) of any variable with thread storage duration defined in the same translationunit as the variable to be initialized.6If the initialization of a non-local variable with static or thread storage duration exits via an exception,std::terminate is called (15.5.1).3.6.31Termination[basic.start.term]Destructors (12.4) for initialized objects (that is, objects whose lifetime (3.8) has begun) with static storageduration are called as a result of returning from main and as a result of calling std::exit (18.5).