The goal of these changes is to expand the meaning of "variable" to encompass both named objects and references, and to apply the term consistently wherever feasible. While doing so, the following miscellaneous issues found during review were also addressed
Change 1.10 intro.multithread paragraph 5 as follows:
... [ Note: ... In general this will be impossible since different threads may observe modifications to differentChange 1.10 intro.multithread paragraph 7 as follows:variablesobjects in inconsistent orders. -- end note ]
... [ Note: ... For atomicChange 1.10 intro.multithread paragraph 12 as follows:variablesobjects, the definition is clear. ... -- end note ]
... [ Note: This states that operations on ordinaryChange 2.1 lex.phases paragraph 1, number 9 as follows:variablesobjects are not visibly reordered. ... -- end note ]
9. All externalChange 3 basic paragraph 3:object and functionentity references are resolved. Library components are linked to satisfy external references tofunctions and objectsentities not defined in the current translation...
An entity is a value, object,Change 3 basic paragraph 6:variable,reference, function, enumerator, type, class member, template, template specialization, namespace, parameter pack, concept, or concept map.
A variable is introduced by the declaration of a reference other than a non-static data member or of an object. The variable's name denotes the object or reference.No change in 3.2 basic.def.odr paragraph 1.
Change 3.2 basic.def.odr paragraph 2 as follows:
...Change 3.2 basic.def.odr paragraph 3 as follows:An objectA variable or non-overloaded function whose name appears as a potentially-evaluated expression is used unless it is an object that satisfies the requirements for appearing in a constant expression...
Every program shall contain exactly one definition of every non-inline function orChange 3.3 basic.scope paragraph 4, bullet 2 as follows:objectvariable that is used in that program...
Change 3.3.1 basic.scope.pdecl paragraph 9 as follows:
- exactly one declaration shall declare a class name or enumeration name that is not a typedef name and the other declarations shall all refer to the same
object,variable or enumerator, or all refer to functions and function templates...
Function declarations at block scope andChange 3.3.11 basic.scope.hiding paragraph 2 as follows:objectvariable declarations with theextern
specifier at block scope refer to declarations that are members of an enclosing namespace...
A class name (9.1 class.name) or enumeration name (7.2 dcl.enum) can be hidden by the name ofChange 3.4.1 basic.lookup.unqual paragraph 14 as follows:an objecta variable, data member, function, or enumerator declared in the same scope. If a class or enumeration name andan objecta variable, data member, function, or enumerator are declared in the same scope (in any order) with the same name, the class or enumeration name is hidden wherever theobjectvariable, data member, function, or enumerator name is visible.
If a variable member of a namespace is defined outside of the scope of its namespace then any nameChange 3.4.3 basic.lookup.qual paragraph 1 as follows:usedthat appears in the definition of thevariablemember (after the declarator-id) is looked up as if the definition of thevariablemember occurred in its namespace. ...
...During the lookup for a name preceding the :: scope resolution operator,Change 3.4.3.2 namespace.qual paragraph 5 as follows:objectvariable, function, and enumerator names are ignored...
During the lookup of a qualified namespace member name, if the lookup finds more than one declaration of the member, and if one declaration introduces a class name or enumeration name and the other declarations either introduce the sameNo change in 3.5 basic.link paragraph 2.objectvariable, the same enumerator or a set of functions, the non-type name hides the class or enumeration name if and only if the declarations are from the same namespace; otherwise (the declarations are from different namespaces), the program is ill-formed. ...
Change 3.5 basic.link paragraph 3 as follows:
A name having namespace scope (3.3.6 basic.scope.namespace) has internal linkage if it is the name ofChange 3.5 basic.link paragraph 4 as follows:
an object, referencea variable, function or function template that is explicitly declared static...an object or referencea variable that is explicitly declared const and neither explicitly declared extern nor previously declared to have external linkage; or- ...
A name having namespace scope has external linkage if it is the name ofChange 3.5 basic.link paragraph 6 as follows:
an object or referencea variable, unless it has internal linkage; or- ...
The name of a function declared in block scope and the name ofChange 3.5 basic.link paragraph 8 as follows:an objecta variable declared by a block scopeextern
declaration have linkage. ...
... A type without linkage shall not be used as the type of a variable or function with linkage, unlessChange 3.5 basic.link paragraph 9 as follows:the variable or functionthat entity has extern "C" linkage (7.5), or ...
Two names that are the same (clause 3) and that are declared in different scopes shall denote the sameChange 3.5 basic.link paragraph 10 as follows:object, referencevariable, function, type, enumerator, template or namespace if ...
...the types specified by all declarations referring to a givenChange the section heading of 3.6.2 basic.start.init as follows:objectvariable or function shall be identical...
3.6.2 Initialization of non-localChange 3.6.2 basic.start.init paragraph 1 as follows:objectsvariables
There are two broad classes of named non-localChange 3.6.2 basic.start.init paragraph 2 as follows:objectsvariables: those with static storage duration (3.7.1 basic.stc.static) and those with thread storage duration (3.7.2 basic.stc.thread). Non-localobjectsvariables with static storage duration are initialized as a consequence of program initiation. Non-localobjectsvariables with thread storage duration are initialized as a consequence of thread execution. ...
Change 3.6.2 basic.start.init paragraph 3 as follows:ObjectsVariables with static storage duration (3.7.1 basic.stc.static) or thread storage duration (3.7.2 basic.stc.thread) shall be zero-initialized (8.5 dcl.init) before any other initialization takes place.... Dynamic initialization of a non-local
objectvariable with static storage duration is either ordered or unordered. Definitions of explicitly specialized class template static data members have ordered initialization. Other class template static data members (i.e., implicitly or explicitly instantiated specializations) have unordered initialization. Otherobjects defined in namespace scopenon-local variables with static storage duration have ordered initialization.ObjectsVariables with ordered initialization defined within a single translation unit shall be initialized in the order of their definitions in the translation unit. If a program starts a thread (30.2 thread.threads), the subsequent initialization ofan objecta variable is unsequenced with respect to the initialization ofan objecta variable defined in a different translation unit. Otherwise, the initialization ofan objecta variable is indeterminately sequenced with respect to the initialization ofan objecta variable defined in a different translation unit. If a program starts a thread, the subsequent unordered initialization ofan objecta variable is unsequenced with respect to every other dynamic initialization. Otherwise, the unordered initialization ofan objecta variable is indeterminately sequenced with respect to every other dynamic initialization. [ Note: This definition permits initialization of a sequence of orderedobjectsvariables concurrently with another sequence. -- end note ] [ Note:8.5.1 dcl.init.aggr describes the order in which aggregate members are initialized.The initialization of local staticobjectsvariables is described in 6.7 stmt.dcl. -- end note ]
An implementation is permitted to perform the initialization ofChange 3.6.2 basic.start.init paragraph 4 as follows:an object of namespace scopea non-local variable with static storage duration as a static initialization even if such initialization is not required to be done statically, provided that
- the dynamic version of the initialization does not change the value of any other object of namespace scope prior to its initialization, and
- the static version of the initialization produces the same value in the initialized
objectvariable as would be produced by the dynamic initialization if allobjectsvariables not required to be initialized statically were initialized dynamically.
It is implementation-defined whether the dynamic initializationChange 3.6.2 basic.start.init paragraph 5 as follows:(8.5 dcl.init, 9.4 class.static, 12.1 class.ctor, 12.6.1 class.expl.init)ofan object of namespace scopea non-local variable with static storage duration is done before the first statement ofmain
. If the initialization is deferred to some point in time after the first statement ofmain
, it shall occur before the first use of any function orobjectvariable defined in the same translation unit as theobjectvariable to be initialized. [ Footnote:An object defined in namespace scopeA non-local variable with static storage duration having initialization with side-effects must be initialized even if it is not used (3.7.1 basic.stc.static). ] ...
It is implementation-defined whether the dynamic initializationChange 3.6.2 basic.start.init paragraph 6 as follows:(8.5 dcl.init, 9.4 class.static, 12.1 class.ctor, 12.6.1 class.expl.init)ofan object of namespace scopea non-local variable with static or thread storage durationand with thread storage durationis done before the first statement of the initial function of the thread. If the initialization is deferred to some point in time after the first statement of the initial function of the thread, it shall occur before the first use of anyobjectvariable with thread storage duration defined in the same translation unit as theobjectvariable to be initialized.
Drafting note: This change (together with the corresponding change in 15.5.1) addressesIf construction or destruction of a non-local static or thread duration object ends in throwing an uncaught exception, the result is to call[ Note: If the initialization of a non-local variable with static or thread storage duration terminates by throwing an exception,std::terminate
(18.7.3.3 terminate)std::terminate
is called (see 15.5.1 except.terminate). ]
const A& a = ( B(), A() )
; assume
B() throws an exception: the B() temporary is not lifetime-extended,
so it's not the "construction of a non-local static duration object",
so the wording falls into a black hole. The next change addresses the
"destruction" case.
Add at the end of 3.6.3 basic.start.term paragraph 1:
... [ Note: If the destruction of a non-local object with static
or thread storage duration terminates by throwing an exception,
std::terminate
is called (see 15.5.1
except.terminate). ]
No change in the rest of 3.6.3: references don't have destructors and
temporaries would be lifetime-extended so that "object with
static/thread storage duration" fits them.
Change 3.7.1 basic.stc.static paragraphs 1 and 2 as follows:
AllNo change in 3.7.1 basic.stc.static paragraph 3.objectsvariables which do not have dynamic storage duration, do not have thread storage duration, and are not local have static storage duration. The storage for theseobjectsentities shall last for the duration of the program (3.6.2 basic.start.init, 3.6.3 basic.start.term).If
an object ofa variable with static storage duration has initialization or a destructor with side effects, it shall not be eliminated even if it appears to be unused, except that a class object or its copy may be eliminated as specified in 12.8 class.copy.
Change 3.7.2 basic.stc.thread paragraphs 1 and 2 as follows:
AllChange 3.7.3 basic.stc.auto paragraphs 1, 2, and 3 as follows:objects and referencesvariables declared with thethread_local
keyword have thread storage duration. The storage for theseobjects and referencesentities shall last for the duration of the thread in which they are created. There is a distinct object or reference per thread, and use of the declared name refers to theobject or referenceentitiy associated with the current thread.
An object or referenceA variable with thread storage duration shall be initialized before its first use and, if constructed, shall be destroyed on thread exit.
LocalChange 3.9.1 basic.fundamental paragraph 6 as follows:objectsvariables explicitly declaredregister
or not explicitly declaredstatic
orextern
have automatic storage duration. The storage for theseobjectsentities lasts until the block in which they are created exits.[ Note: these
objectsvariables are initialized and destroyed as described in 6.7. -- end note ]If a
named automatic objectvariable with automatic storage duration has initialization or a destructor with side effects, it shall not be destroyed before the end of its block, nor shall it be eliminated as an optimization even if it appears to be unused, except that a class object or its copy may be eliminated as specified in 12.8 class.copy.
Values of typeChange 5.1 expr.prim paragraph 4 as follows:bool
are eithertrue
orfalse
. [ Footnote: Using abool
value in ways described by this International Standard as "undefined," such as by examining the value of an uninitialized automaticvariableobject, might cause it to behave as if it is neithertrue
norfalse
. ] ...
... [ Note: the use of :: allowsDrafting note: This is an en passant fix.a type, an object, a function, an enumerator, or a namespacean entity declared in the global namespace to be referred to even if itsidentifiername has been hidden (3.4.3 basic.lookup.qual). -- end note ]
No change in 5.1 expr.prim paragraph 7.
No change in 5.1 expr.prim paragraph 8.
Change 5.1.2 expr.prim.lambda paragraph 9 as follows:
A lambda-expression's compound-statement can use (see above)Change 5.1.2 expr.prim.lambda paragraph 10 as follows:this
from an immediately-enclosing member function definition, as well as variablesand referenceswith automatic storage duration from an immediately-enclosing function definition or lambda-expression, provided these entities are captured (as described below). Any other use (3.2 basic.def.odr) of a variableor referencewith automatic storage duration declared outside the lambda-expression is ill-formed. [ Example: ...
The identifiers in a capture-list are looked up using the usual rules for unqualified name lookup (3.4.1 basic.lookup.unqual); each such lookup shall find a variableChange 5.1.2 expr.prim.lambda paragraph 11 as follows:or referencewith automatic storage duration. An entity (i.e. a variable, a reference,orthis
) is said to be explicitly captured if it appears in the lambda-expression's capture-list. An explicitly captured entity is used (3.2 basic.def.odr).
If a lambda-expression has an associated capture-default and its compound-statement uses (3.2 basic.def.odr)Change 5.2.9 expr.static.cast paragraph 5 as follows:this
or a variableor referencewith automatic storage duration declared in an enclosing function or lambda-expression and the used entity is not explicitly captured, then the used entity is said to be implicitly captured. ...
... [ Note: however, if the value is in a temporaryChange 5.19 expr.const paragraph 2 bullet 4 sub-bullet 1 as follows:variableobject (12.2 class.temporary), the destructor for thatvariableobject is not executed until the usual time, and the value of thevariableobject is preserved for the purpose of executing the destructor. -- end note ] ...
Change 6.5.1 stmt.while paragraph 2 as follows:
- ...
- an lvalue of effective integral type that refers to a non-volatile const
variable or static data memberobject initialized with constant expressions, or
TheChange 6.6 stmt.jump paragraph 2 as follows:objectvariable created in a condition is destroyed and created with each iteration of the loop...
On exit from a scope (however accomplished),No change in 6.7 stmt.dcl paragraph 2.variablesobjects with automatic storage duration (3.7.3) that have been constructed in that scope are destroyed in the reverse order of their construction. ... Transfer out of a loop, out of a block, or back past an initialized variable with automatic storage duration involves the destruction ofvariablesobjects with automatic storage duration that are in scope at the point transferred from but not at the point transferred to. ...
No change in 6.7 stmt.dcl paragraph 3.
Change 6.7 stmt.dcl paragraph 4:
The zero-initialization (8.5 dcl.init) of all localChange 6.7 stmt.dcl paragraph 5 as follows:objectsvariables with static storage duration (3.7.1 basic.stc.static) or thread storage duration (3.7.2 basic.stc.thread) is performed before any other initialization takes place. ... An implementation is permitted to perform early initialization of other localobjectsvariables with static or thread storage duration under the same conditions that an implementation is permitted to statically initializean objecta variable with static or thread storage duration in namespace scope (3.6.2 basic.start.init). Otherwise suchan objecta variable is initialized the first time control passes through its declaration; such an object is considered initialized upon the completion of its initialization. ... If control enters the declaration concurrently while theobjectvariable is being initialized, the concurrent execution shall wait for completion of the initialization. [ Footnote: ... ] If control re-enters the declaration recursively while theobjectvariable is being initialized, the behavior is undefined. ...
The destructor for a local object with static or thread storage duration will be executed if and only ifChange 7.1.1 dcl.stc paragraphs 1-8 as follows:the variableit was constructed. ...
... IfNo change required for 7.1.2 dcl.fct.spec paragraph 4:thread_local
appears in any declaration ofan object or referencea variable it shall be present in all declarations of thatobject or referenceentity. ...The register specifier shall be applied only to names of
objectsvariables declared in a block (6.3 stmt.block) or to function parameters (8.4 dcl.fct.def). It specifies that the namedobjectvariable has automatic storage duration (3.7.3 basic.stc.auto).An objectA variable declared without a storage-class-specifier at block scope or declared as a function parameter has automatic storage duration by default.A
register
specifier is a hint to the implementation that theobjectvariable so declared will be heavily used. [ Note: the hint can be ignored and in most implementations it will be ignored if the address of theobjectvariable is taken. -- end note ]The
thread_local
specifier shall be applied only to the names ofobjects or referencesvariables of namespace scope and to the names ofobjects or referencesvariables of block scope that also specifystatic
. It specifies that the namedobject or referenceentity has thread storage duration (3.7.2 basic.stc.thread).The
static
specifier can be applied only to names ofobjectsvariables and functions and to anonymous unions (9.5 class.union). There can be no static function declarations within a block, nor any static function parameters. A static specifier used in the declaration ofan objecta variable declares theobjectvariable to have static storage duration (3.7.1 basic.stc.static), unless accompanied by thethread_local
specifier, which declares the object to have thread storage duration (3.7.2 basic.stc.thread). Astatic
specifier can be used in declarations of class members; 9.4 class.static describes its effect. For the linkage of a name declared with a static specifier, see 3.5 basic.link.The
extern
specifier can be applied only to the names ofobjectsvariables and functions. Theextern
specifier cannot be used in the declaration of class members or function parameters. For the linkage of a name declared with anextern
specifier, see 3.5 basic.link. [ Note: Theextern
keyword can also be used in explicit-instantiations and linkage-specifications, but it is not a storage-class-specifier in such contexts. -- end note ]A name declared in a namespace scope without a storage-class-specifier has external linkage unless it has internal linkage because of a previous declaration and provided it is not declared
const
. Objects declaredconst
and not explicitly declaredextern
have internal linkage.The linkages implied by successive declarations for a given entity shall agree. That is, within a given scope, each declaration declaring the same
objectvariable name or the same overloading of a function name shall imply the same linkage. Each function in a given set of overloaded functions can have a different linkage, however. ...
A static local variable in an extern inline function always refers to the same object.Change 7.1.6.4 dcl.spec.auto paragraph 1 as follows: x
TheChange 7.1.6.4 dcl.spec.auto paragraph 3 as follows:auto
type-specifier signifies that the type ofan objecta variable being declared shall be deduced from its initializer or specified explicitly at the end of a function declarator.
Otherwise, the type of theChange 7.1.6.4 dcl.spec.auto paragraph 4 as follows:objectvariable is deduced from its initializer. The name of theobjectvariable being declared shall not appear in the initializer expression. This use ofauto
is allowed when declaringobjectsvariables in a block (6.3 stmt.block), in namespace scope (3.3.6 basic.scope.namespace), and in a for-init-statement (6.5.3 stmt.for). ...
TheChange 7.3.1.1 namespace.unnamed paragraph 2 as follows:auto
type-specifier can also be used in declaringan objecta variable in the condition of a selection statement...
The use of theChange 7.3.4 namespace.udir paragraph 6 as follows:static
keyword is deprecated when declaringobjectsvariables in a namespace scope (see annex D depr); the unnamed-namespace provides a superior alternative.
[ Note: in particular, the name ofNo change in 7.5 dcl.link paragraph 1, effectively expanding language linkage to (non-member) references.an objecta variable, function or enumerator does not hide the name of a class or enumeration declared in a different namespace. ... ]
No change in 7.6.2 dcl.align paragraph 1, effectively expanding alignment to non-member references.
Change 8 dcl.decl paragraph 1 as follows:
A declarator declares a singleChange 8 dcl.decl paragraph 2 as follows:objectvariable, function, or type, within a declaration. ...
The specifiers indicate the type, storage class or other properties of theChange 8.1 dcl.name paragraph 1 as follows:objects, functions or typedefsentities being declared. The declarators specify the names of theseobjects, functions or typedefsentities, and (optionally) modify the type of the specifiers with operators such as * (pointer to) and () (function returning). ...
... This can be done with a type-id, which is syntactically a declaration forChange 8.5 dcl.init paragraph 1:an objecta variable or function of that type that omits the name of theobject or functionentity.
... The identifier designatesNo change in 8.5 dcl.init paragraph 2.an object or referencea variable being initialized. ...
Change 8.5 dcl.init paragraphs 4 as follows:
The order of initialization ofNo change in 8.5.3 dcl.init.ref paragraph 1.static objectsvariables with static storage duration is described in 3.6 basic.start and 6.7 stmt.dcl. -- end note ]
Change 9.1 class.name paragraph 2:
A class declaration introduces the class name into the scope where it is declared and hides any class,Change 9.4.2 class.static.data paragraph 6 as follows:objectvariable, function, or other declaration of that name in an enclosing scope (3.3 basic.scope). If a class name is declared in a scope wherean objecta variable, function, or enumerator of the same name is also declared, then when both declarations are in scope, the class can be referred to only using an elaborated-type-specifier (3.4.4 basic.lookup.elab). ...
Static data members are initialized and destroyed exactly like non-localNo change in 9.8 class.local paragraph 1.objectsvariables (3.6.2 basic.start.init, 3.6.3 basic.start.term).
Change 10.2 class.member.lookup paragraph 4 as follows:
... [ Note: Looking up a name in an elaborated-type-specifier (3.4.4 basic.lookup.elab) or base-specifier (clause 10 class.derived), for instance, ignores all non-type declarations, while looking up a name in a nested-name-specifier (3.4.3 basic.lookup.qual) ignores function,No change to 13.4 over.over paragraph 1 bullet 1.objectvariable, and enumerator declarations. ...
Change 14 temp paragraph 5 as follows:
A class template shall not have the same name as any other template, class, function,No change in 14.8 temp.fct.spec paragraph 2.objectvariable, reference, enumeration, enumerator, namespace, or type in the same scope...
Change 15.5.1 except.terminate paragraph 1 bullet 4 as follows:
- when
constructioninitialization or destruction of a non-localobjectvariable with static or thread storage duration (3.6.2 basic.start.init, 3.6.3 basic.start.term)exits usingterminates by throwing an exception(3.6.2 basic.start.init), or