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:
variablesin inconsistent orders. -- end note ]
... [ Note: ... For atomicChange 1.10 intro.multithread paragraph 12 as follows:
variables, the definition is clear. ... -- end note ]
... [ Note: This states that operations on ordinaryChange 2.1 lex.phases paragraph 1, number 9 as follows:
variablesare not visibly reordered. ... -- end note ]
9. All externalChange 3 basic paragraph 3:
object and functionreferences are resolved. Library components are linked to satisfy external references to functions and objectsnot 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 an object. The variable's name denotes the object .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 objector 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:
objectthat 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,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:
objectdeclarations with the
externspecifier 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 object, function, or enumerator declared in the same scope. If a class or enumeration name and an object, function, or enumerator are declared in the same scope (in any order) with the same name, the class or enumeration name is hidden wherever the object, 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:
usedin the definition of the variablemember (after the declarator-id) is looked up as if the definition of the variablemember occurred in its namespace. ...
...During the lookup for a name preceding the :: scope resolution operator,Change 18.104.22.168 namespace.qual paragraph 5 as follows:
object, 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.
object, 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, reference, function or function template that is explicitly declared static...
an object or referencethat 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 reference, 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 objectdeclared by a block scope
externdeclaration 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 functionhas 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, reference, 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:
objector function shall be identical...
3.6.2 Initialization of non-localChange 3.6.2 basic.start.init paragraph 1 as follows:
There are two broad classes of named non-localChange 3.6.2 basic.start.init paragraph 2 as follows:
objects: those with static storage duration (3.7.1 basic.stc.static) and those with thread storage duration (3.7.2 basic.stc.thread). Non-local objectswith static storage duration are initialized as a consequence of program initiation. Non-local objectswith thread storage duration are initialized as a consequence of thread execution. ...
Change 3.6.2 basic.start.init paragraph 3 as follows:
Objectswith 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
objectwith 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. Other objects defined in namespace scopehave ordered initialization. Objectswith 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 of an objectis unsequenced with respect to the initialization of an objectdefined in a different translation unit. Otherwise, the initialization of an objectis indeterminately sequenced with respect to the initialization of an objectdefined in a different translation unit. If a program starts a thread, the subsequent unordered initialization of an objectis unsequenced with respect to every other dynamic initialization. Otherwise, the unordered initialization of an objectis indeterminately sequenced with respect to every other dynamic initialization. [ Note: This definition permits initialization of a sequence of ordered objectsconcurrently 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 static objectsis 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 scopeas 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
objectas would be produced by the dynamic initialization if all objectsnot 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)of an object of namespace scopewith static storage duration is done before the first statement of
main. If the initialization is deferred to some point in time after the first statement of
main, it shall occur before the first use of any function or
objectdefined in the same translation unit as the objectto be initialized. [ Footnote: An object defined in namespace scopehaving 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)of an object of namespace scope and 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 any objectwith thread storage duration defined in the same translation unit as the objectto be initialized.
Drafting note: This change (together with the corresponding change in 15.5.1) addresses
If construction or destruction of a non-local static or thread duration object ends in throwing an uncaught exception, the result is to call
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:
...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.
objectswhich do not have dynamic storage duration, do not have thread storage duration, and are not local have static storage duration. The storage for these objectsshall last for the duration of the program (3.6.2 basic.start.init, 3.6.3 basic.start.term).
an object ofstatic 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 referencesdeclared with the
thread_localkeyword have thread storage duration. The storage for these
objects and referencesshall 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 the object or referenceassociated with the current thread.
An object or referencewith 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:
registeror not explicitly declared
externhave automatic storage duration. The storage for these
objectslasts until the block in which they are created exits.
[ Note: these
objectsare initialized and destroyed as described in 6.7. -- end note ]
named automatic objecthas 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:
false. [ Footnote: Using a
boolvalue in ways described by this International Standard as "undefined," such as by examining the value of an uninitialized automatic
variable, might cause it to behave as if it is neither
false. ] ...
... [ Note: the use of :: allowsDrafting note: This is an en passant fix.
a type, an object, a function, an enumerator, or a namespacedeclared in the global namespace to be referred to even if its identifierhas 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:
thisfrom an immediately-enclosing member function definition, as well as variables
and 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 variable or 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,or
this) 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:
thisor a variable
or 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:
variable(12.2 class.temporary), the destructor for that variableis not executed until the usual time, and the value of the variableis 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 memberinitialized with constant expressions, or
TheChange 6.6 stmt.jump paragraph 2 as follows:
objectcreated 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.
variableswith 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 of variableswith 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:
objectswith 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 local objectswith static or thread storage duration under the same conditions that an implementation is permitted to statically initialize an objectwith static or thread storage duration in namespace scope (3.6.2 basic.start.init). Otherwise such an objectis 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 the objectis being initialized, the concurrent execution shall wait for completion of the initialization. [ Footnote: ... ] If control re-enters the declaration recursively while the objectis 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 variablewas constructed. ...
... IfNo change required for 7.1.2 dcl.fct.spec paragraph 4:
thread_localappears in any declaration of
an object or referenceit shall be present in all declarations of that object or reference. ...
The register specifier shall be applied only to names of
objectsdeclared in a block (6.3 stmt.block) or to function parameters (8.4 dcl.fct.def). It specifies that the named objecthas automatic storage duration (3.7.3 basic.stc.auto). An objectdeclared without a storage-class-specifier at block scope or declared as a function parameter has automatic storage duration by default.
registerspecifier is a hint to the implementation that the
objectso declared will be heavily used. [ Note: the hint can be ignored and in most implementations it will be ignored if the address of the objectis taken. -- end note ]
thread_localspecifier shall be applied only to the names of
objects or referencesof namespace scope and to the names of objects or referencesof block scope that also specify
static. It specifies that the named
object or referencehas thread storage duration (3.7.2 basic.stc.thread).
staticspecifier can be applied only to names of
objectsand 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 of an objectdeclares the objectto have static storage duration (3.7.1 basic.stc.static), unless accompanied by the
thread_localspecifier, which declares the object to have thread storage duration (3.7.2 basic.stc.thread). A
staticspecifier 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.
externspecifier can be applied only to the names of
objectsand functions. The
externspecifier cannot be used in the declaration of class members or function parameters. For the linkage of a name declared with an
externspecifier, see 3.5 basic.link. [ Note: The
externkeyword 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 declared
constand not explicitly declared
externhave 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
objectname 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 22.214.171.124 dcl.spec.auto paragraph 1 as follows: x
TheChange 126.96.36.199 dcl.spec.auto paragraph 3 as follows:
autotype-specifier signifies that the type of
an objectbeing declared shall be deduced from its initializer or specified explicitly at the end of a function declarator.
Otherwise, the type of theChange 188.8.131.52 dcl.spec.auto paragraph 4 as follows:
objectis deduced from its initializer. The name of the objectbeing declared shall not appear in the initializer expression. This use of
autois allowed when declaring
objectsin 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 184.108.40.206 namespace.unnamed paragraph 2 as follows:
autotype-specifier can also be used in declaring
an objectin the condition of a selection statement...
The use of theChange 7.3.4 namespace.udir paragraph 6 as follows:
statickeyword is deprecated when declaring
objectsin 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 object, 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:
object, 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 typedefsbeing declared. The declarators specify the names of these objects, functions or typedefs, 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 objector function of that type that omits the name of the object or function.
... The identifier designatesNo change in 8.5 dcl.init paragraph 2.
an object or referencebeing 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 objectsis 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:
object, function, or other declaration of that name in an enclosing scope (3.3 basic.scope). If a class name is declared in a scope where an object, 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.
objects(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.
object, 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.
object, reference, enumeration, enumerator, namespace, or type in the same scope...
Change 15.5.1 except.terminate paragraph 1 bullet 4 as follows:
constructionor destruction of a non-local objectwith static or thread storage duration exits usingan exception (3.6.2 basic.start.init), or