This commit is contained in:
2025-10-25 03:02:53 +03:00
commit 043225d523
3416 changed files with 681196 additions and 0 deletions

153
cppdraft/basic/align.md Normal file
View File

@@ -0,0 +1,153 @@
[basic.align]
# 6 Basics [[basic]](./#basic)
## 6.8 Memory and objects [[basic.memobj]](basic.memobj#basic.align)
### 6.8.3 Alignment [basic.align]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3727)
Object types have [*alignment requirements*](#def:alignment_requirement,implementation-defined "6.8.3Alignment[basic.align]") ([[basic.fundamental]](basic.fundamental "6.9.2Fundamental types"), [[basic.compound]](basic.compound "6.9.4Compound types"))
which place restrictions on the addresses at which an object of that type
may be allocated[.](#1.sentence-1)
An [*alignment*](#def:alignment "6.8.3Alignment[basic.align]") is an implementation-defined
integer value representing the number of bytes between successive addresses
at which a given object can be allocated[.](#1.sentence-2)
An object type imposes an alignment
requirement on every object of that type; stricter alignment can be requested
using the alignment specifier ([[dcl.align]](dcl.align "9.13.2Alignment specifier"))[.](#1.sentence-3)
Attempting to create an object ([[intro.object]](intro.object "6.8.2Object model")) in storage that
does not meet the alignment requirements of the object's type
is undefined behavior[.](#1.sentence-4)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3739)
A [*fundamental alignment*](#def:alignment,fundamental "6.8.3Alignment[basic.align]") is represented by an alignment
less than or equal to the greatest alignment supported by the implementation in
all contexts, which is equal toalignof(std::max_align_t) ([[support.types]](support.types "17.2Common definitions"))[.](#2.sentence-1)
The alignment required for a type may be different when it is used as the type
of a complete object and when it is used as the type of a subobject[.](#2.sentence-2)
[*Example [1](#example-1)*: struct B { long double d; };struct D : virtual B { char c; };
When D is the type of a complete object, it will have a subobject of
type B, so it must be aligned appropriately for a long double[.](#2.sentence-3)
If D appears as a subobject of another object that also has B as a virtual base class, the B subobject might be part of a different
subobject, reducing the alignment requirements on the D subobject[.](#2.sentence-4)
— *end example*]
The result of the alignof operator reflects the alignment
requirement of the type in the complete-object case[.](#2.sentence-5)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3761)
An [*extended alignment*](#def:alignment,extended "6.8.3Alignment[basic.align]") is represented by an alignment
greater than alignof(std::max_align_t)[.](#3.sentence-1)
It is implementation-defined
whether any extended alignments are supported and the contexts in which they are
supported ([[dcl.align]](dcl.align "9.13.2Alignment specifier"))[.](#3.sentence-2)
A type having an extended alignment
requirement is an [*over-aligned type*](#def:type,over-aligned "6.8.3Alignment[basic.align]")[.](#3.sentence-3)
[*Note [1](#note-1)*:
Every over-aligned type is or contains a class type
to which extended alignment applies (possibly through a non-static data member)[.](#3.sentence-4)
— *end note*]
A [*new-extended alignment*](#def:alignment,new-extended "6.8.3Alignment[basic.align]") is represented by
an alignment greater than __STDCPP_DEFAULT_NEW_ALIGNMENT__ ([[cpp.predefined]](cpp.predefined "15.12Predefined macro names"))[.](#3.sentence-5)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3774)
Alignments are represented as values of the type std::size_t[.](#4.sentence-1)
Valid alignments include only those values returned by an alignof expression for the fundamental types plus an additional implementation-defined
set of values, which may be empty[.](#4.sentence-2)
Every alignment value shall be a non-negative integral power of two[.](#4.sentence-3)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3782)
Alignments have an order from [*weaker*](#def:alignment,weaker "6.8.3Alignment[basic.align]") to[*stronger*](#def:alignment,stronger "6.8.3Alignment[basic.align]") or [*stricter*](#def:alignment,stricter "6.8.3Alignment[basic.align]") alignments[.](#5.sentence-1)
Stricter
alignments have larger alignment values[.](#5.sentence-2)
An address that satisfies an alignment
requirement also satisfies any weaker valid alignment requirement[.](#5.sentence-3)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3788)
The alignment requirement of a complete type can be queried using analignof expression ([[expr.alignof]](expr.alignof "7.6.2.6Alignof"))[.](#6.sentence-1)
Furthermore,
the narrow character types ([[basic.fundamental]](basic.fundamental "6.9.2Fundamental types")) shall have the weakest
alignment requirement[.](#6.sentence-2)
[*Note [2](#note-2)*:
This enables the ordinary character types to be used as the
underlying type for an aligned memory area ([[dcl.align]](dcl.align "9.13.2Alignment specifier"))[.](#6.sentence-3)
— *end note*]
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3798)
Comparing alignments is meaningful and provides the obvious results:
- [(7.1)](#7.1)
Two alignments are equal when their numeric values are equal[.](#7.1.sentence-1)
- [(7.2)](#7.2)
Two alignments are different when their numeric values are not equal[.](#7.2.sentence-1)
- [(7.3)](#7.3)
When an alignment is larger than another it represents a stricter alignment[.](#7.3.sentence-1)
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3807)
[*Note [3](#note-3)*:
The runtime pointer alignment function ([[ptr.align]](ptr.align "20.2.5Pointer alignment"))
can be used to obtain an aligned pointer within a buffer;
an [*alignment-specifier*](dcl.attr.grammar#nt:alignment-specifier "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") ([[dcl.align]](dcl.align "9.13.2Alignment specifier"))
can be used to align storage explicitly[.](#8.sentence-1)
— *end note*]
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3815)
If a request for a specific extended alignment in a specific context is not
supported by an implementation, the program is ill-formed[.](#9.sentence-1)

264
cppdraft/basic/compound.md Normal file
View File

@@ -0,0 +1,264 @@
[basic.compound]
# 6 Basics [[basic]](./#basic)
## 6.9 Types [[basic.types]](basic.types#basic.compound)
### 6.9.4 Compound types [basic.compound]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5789)
Compound types can be constructed in the following ways:
- [(1.1)](#1.1)
[*arrays*](#def:type,array "6.9.4Compound types[basic.compound]") of objects of a given type, [[dcl.array]](dcl.array "9.3.4.5Arrays");
- [(1.2)](#1.2)
[*functions*](dcl.fct#def:type,function "9.3.4.6Functions[dcl.fct]"), which have parameters of given types and returnvoid or a result of a given type, [[dcl.fct]](dcl.fct "9.3.4.6Functions");
- [(1.3)](#1.3)
[*pointers*](#def:type,pointer "6.9.4Compound types[basic.compound]") to cv void or objects or functions (including
static members of classes) of a given type, [[dcl.ptr]](dcl.ptr "9.3.4.2Pointers");
- [(1.4)](#1.4)
[*references*](#def:reference "6.9.4Compound types[basic.compound]") to objects or functions of a given
type, [[dcl.ref]](dcl.ref "9.3.4.3References")[.](#1.4.sentence-1)
There are two types of references:
* [(1.4.1)](#1.4.1)
lvalue reference
* [(1.4.2)](#1.4.2)
rvalue reference
- [(1.5)](#1.5)
[*classes*](#def:class "6.9.4Compound types[basic.compound]") containing a sequence of class members ([[class]](class "11Classes"), [[class.mem]](class.mem "11.4Class members")),
and a set of restrictions
on the access to these entities ([[class.access]](class.access "11.8Member access control"));
- [(1.6)](#1.6)
[*unions*](#def:union "6.9.4Compound types[basic.compound]"), which are classes capable of containing objects of
different types at different times, [[class.union]](class.union "11.5Unions");
- [(1.7)](#1.7)
[*enumerations*](#def:enum "6.9.4Compound types[basic.compound]"),
which comprise a set of named constant values, [[dcl.enum]](dcl.enum "9.8.1Enumeration declarations");
- [(1.8)](#1.8)
[*pointers to non-static class members*](#def:pointer_to_member "6.9.4Compound types[basic.compound]"),[31](#footnote-31 "Static class members are objects or functions, and pointers to them are ordinary pointers to objects or functions.") which identify members of a given
type within objects of a given class, [[dcl.mptr]](dcl.mptr "9.3.4.4Pointers to members")[.](#1.8.sentence-1)
Pointers to data members and pointers to member functions are collectively
called [*pointer-to-member*](#def:pointer-to-member "6.9.4Compound types[basic.compound]") types[.](#1.8.sentence-2)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5837)
These methods of constructing types can be applied recursively;
restrictions are mentioned in [[dcl.meaning]](dcl.meaning "9.3.4Meaning of declarators")[.](#2.sentence-1)
Constructing a type such that the number of
bytes in its object representation exceeds the maximum value representable in
the type std::size_t ([[support.types]](support.types "17.2Common definitions")) is ill-formed[.](#2.sentence-2)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5844)
The type of a pointer to cv void or a pointer to an object type is
called an [*object pointer type*](#def:object_pointer_type "6.9.4Compound types[basic.compound]")[.](#3.sentence-1)
[*Note [1](#note-1)*:
A pointer to void does not have a pointer-to-object type, however, because void is not
an object type[.](#3.sentence-2)
— *end note*]
The type of a pointer that can designate a function
is called a [*function pointer type*](#def:function_pointer_type "6.9.4Compound types[basic.compound]")[.](#3.sentence-3)
A pointer to an object of type T is referred to as a “pointer toT”[.](#3.sentence-4)
[*Example [1](#example-1)*:
A pointer to an object of type int is
referred to as “pointer to int” and a pointer to an object of
class X is called a “pointer to X”[.](#3.sentence-5)
— *end example*]
Except for pointers to static members, text referring to “pointers”
does not apply to pointers to members[.](#3.sentence-6)
Pointers to incomplete types are
allowed although there are restrictions on what can be done with
them ([[basic.types.general]](basic.types.general "6.9.1General"))[.](#3.sentence-7)
Every value of pointer type is one of the following:
- [(3.1)](#3.1)
a [*pointer to*](#def:pointer_to "6.9.4Compound types[basic.compound]") an object or function (the pointer is said to [*point*](#def:point "6.9.4Compound types[basic.compound]") to the object or function), or
- [(3.2)](#3.2)
a [*pointer past the end of*](#def:pointer_past_the_end_of "6.9.4Compound types[basic.compound]") an object ([[expr.add]](expr.add "7.6.6Additive operators")), or
- [(3.3)](#3.3)
the [*null pointer value*](#def:value,null_pointer "6.9.4Compound types[basic.compound]") for that type, or
- [(3.4)](#3.4)
an [*invalid pointer value*](#def:value,invalid_pointer "6.9.4Compound types[basic.compound]")[.](#3.sentence-8)
A value of a
pointer type
that is a pointer to or past the end of an object[*represents the address*](#def:represents_the_address "6.9.4Compound types[basic.compound]") of
the first byte in memory ([[intro.memory]](intro.memory "6.8.1Memory model")) occupied by the object[32](#footnote-32 "For an object that is not within its lifetime, this is the first byte in memory that it will occupy or used to occupy.") or the first byte in memory
after the end of the storage occupied by the object,
respectively[.](#3.sentence-9)
[*Note [2](#note-2)*:
A pointer past the end of an object ([[expr.add]](expr.add "7.6.6Additive operators"))
is not considered to point to an unrelated object
of the object's type,
even if the unrelated object is located at that address[.](#3.sentence-10)
— *end note*]
For purposes of pointer arithmetic ([[expr.add]](expr.add "7.6.6Additive operators"))
and comparison ([[expr.rel]](expr.rel "7.6.9Relational operators"), [[expr.eq]](expr.eq "7.6.10Equality operators")),
a pointer past the end of the last element of
an array x of n elements
is considered to be equivalent to
a pointer to a hypothetical array element n of x, and
an object of type T that is not an array element
is considered to belong to an array with one element of type T[.](#3.sentence-11)
The value representation of
pointer types is implementation-defined[.](#3.sentence-12)
Pointers to
layout-compatible types shall
have the same value representation and alignment
requirements ([[basic.align]](basic.align "6.8.3Alignment"))[.](#3.sentence-13)
[*Note [3](#note-3)*:
Pointers to [over-aligned types](basic.align#def:type,over-aligned "6.8.3Alignment[basic.align]") have no special
representation, but their range of valid values is restricted by the extended
alignment requirement[.](#3.sentence-14)
— *end note*]
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5917)
A pointer value P is[*valid in the context of*](#def:valid_in_the_context_of "6.9.4Compound types[basic.compound]") an evaluation E if P is a pointer to function or a null pointer value, or
if it is a pointer to or past the end of an object O andE happens before the end of the duration of the region of storage for O[.](#4.sentence-1)
If a pointer value P is used in an evaluation E andP is not valid in the context of E,
then the behavior is undefined if E is
an indirection ([[expr.unary.op]](expr.unary.op "7.6.2.2Unary operators")) or
an invocation of a deallocation function ([[basic.stc.dynamic.deallocation]](basic.stc.dynamic.deallocation "6.8.6.5.3Deallocation functions")),
and implementation-defined otherwise[.](#4.sentence-2)[33](#footnote-33 "Some implementations might define that copying such a pointer value causes a system-generated runtime fault.")
[*Note [4](#note-4)*:
P can be valid in the context of E even
if it points to a type unrelated to that of O or
if O is not within its lifetime,
although further restrictions apply
to such pointer values ([[basic.life]](basic.life "6.8.4Lifetime"), [[basic.lval]](basic.lval "7.2.1Value category"), [[expr.add]](expr.add "7.6.6Additive operators"))[.](#4.sentence-3)
— *end note*]
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5942)
Two objects *a* and *b* are [*pointer-interconvertible*](#def:pointer-interconvertible "6.9.4Compound types[basic.compound]") if
- [(5.1)](#5.1)
they are the same object, or
- [(5.2)](#5.2)
one is a union object and
the other is a non-static data member of that object ([[class.union]](class.union "11.5Unions")), or
- [(5.3)](#5.3)
one is a standard-layout class object and
the other is the first non-static data member of that object or
any base class subobject of that object ([[class.mem]](class.mem "11.4Class members")), or
- [(5.4)](#5.4)
there exists an object *c* such that*a* and *c* are pointer-interconvertible, and*c* and *b* are pointer-interconvertible[.](#5.sentence-1)
If two objects are pointer-interconvertible,
then they have the same address,
and it is possible to obtain a pointer to one
from a pointer to the other
via a reinterpret_cast ([[expr.reinterpret.cast]](expr.reinterpret.cast "7.6.1.10Reinterpret cast"))[.](#5.sentence-2)
[*Note [5](#note-5)*:
An array object and its first element are not pointer-interconvertible,
even though they have the same address[.](#5.sentence-3)
— *end note*]
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5969)
A byte of storage *b* is [*reachable through*](#def:storage,reachable_through_a_pointer_value "6.9.4Compound types[basic.compound]") a pointer value that points to an object *x* if there is an object *y*,
pointer-interconvertible with *x*,
such that *b* is within the storage occupied by*y*, or the immediately-enclosing array object
if *y* is an array element[.](#6.sentence-1)
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5979)
A pointer to cv void can be used to point to objects of
unknown type[.](#7.sentence-1)
Such a pointer shall be able to hold any object pointer[.](#7.sentence-2)
An object of type “pointer to cv void”
shall have the same representation and alignment
requirements as an object of type “pointer to cv char”[.](#7.sentence-3)
[31)](#footnote-31)[31)](#footnoteref-31)
Static class members are objects or functions, and pointers to them are
ordinary pointers to objects or functions[.](#footnote-31.sentence-1)
[32)](#footnote-32)[32)](#footnoteref-32)
For an object that is not within its lifetime,
this is the first byte in memory that it will occupy or used to occupy[.](#footnote-32.sentence-1)
[33)](#footnote-33)[33)](#footnoteref-33)
Some implementations might define that
copying such a pointer value causes a system-generated runtime fault[.](#footnote-33.sentence-1)

494
cppdraft/basic/contract.md Normal file
View File

@@ -0,0 +1,494 @@
[basic.contract]
# 6 Basics [[basic]](./#basic)
## 6.11 Contract assertions [basic.contract]
### [6.11.1](#general) General [[basic.contract.general]](basic.contract.general)
[1](#general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7567)
[*Contract assertions*](#def:contract_assertion "6.11.1General[basic.contract.general]") allow the programmer to specify
properties of the state of the program
that are expected to hold at
certain points during execution[.](#general-1.sentence-1)
Contract assertions are introduced by[*precondition-specifier*](dcl.contract.func#nt:precondition-specifier "9.4.1General[dcl.contract.func]")*s*,[*postcondition-specifier*](dcl.contract.func#nt:postcondition-specifier "9.4.1General[dcl.contract.func]")*s* ([[dcl.contract.func]](dcl.contract.func "9.4.1General")), and[*assertion-statement*](stmt.contract.assert#nt:assertion-statement "8.9Assertion statement[stmt.contract.assert]")*s* ([[stmt.contract.assert]](stmt.contract.assert "8.9Assertion statement"))[.](#general-1.sentence-2)
[2](#general-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7578)
Each contract assertion has a [*contract-assertion predicate*](#def:predicate,contract-assertion "6.11.1General[basic.contract.general]"),
which is an expression of type bool[.](#general-2.sentence-1)
[*Note [1](#general-note-1)*:
The value of the predicate is used to identify program states that are
expected[.](#general-2.sentence-2)
— *end note*]
[3](#general-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7587)
An invocation of the macro va_start ([[cstdarg.syn]](cstdarg.syn "17.14.2Header <cstdarg> synopsis"))
shall not be a subexpression
of the predicate of a contract assertion,
no diagnostic required[.](#general-3.sentence-1)
[4](#general-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7593)
[*Note [2](#general-note-2)*:
Within the predicate of a contract assertion,[*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1General[expr.prim.id.general]")*s* referring to
variables declared outside the contract assertion
are const ([[expr.prim.id.unqual]](expr.prim.id.unqual "7.5.5.2Unqualified names")),this is a pointer to const ([[expr.prim.this]](expr.prim.this "7.5.3This")),
and the result object can be named
if a [*result-name-introducer*](dcl.contract.res#nt:result-name-introducer "9.4.2Referring to the result object[dcl.contract.res]") ([[dcl.contract.res]](dcl.contract.res "9.4.2Referring to the result object")) has been specified[.](#general-4.sentence-1)
— *end note*]
### [6.11.2](#eval) Evaluation [[basic.contract.eval]](basic.contract.eval)
[1](#eval-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7606)
An evaluation of a contract assertion
uses one of the following four [*evaluation semantics*](#def:evaluation_semantics "6.11.2Evaluation[basic.contract.eval]"):[*ignore*](#def:contract_evaluation_semantics,ignore "6.11.2Evaluation[basic.contract.eval]"),[*observe*](#def:contract_evaluation_semantics,observe "6.11.2Evaluation[basic.contract.eval]"),[*enforce*](#def:contract_evaluation_semantics,enforce "6.11.2Evaluation[basic.contract.eval]"), or[*quick-enforce*](#def:contract_evaluation_semantics,quick-enforce "6.11.2Evaluation[basic.contract.eval]")[.](#eval-1.sentence-1)
Observe, enforce, and quick-enforce are [*checking semantics*](#def:contract_evaluation_semantics,checking "6.11.2Evaluation[basic.contract.eval]");
enforce and quick-enforce are [*terminating semantics*](#def:contract_evaluation_semantics,terminating "6.11.2Evaluation[basic.contract.eval]")[.](#eval-1.sentence-2)
[2](#eval-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7619)
It isimplementation-defined
which evaluation semantic is used
for any given evaluation of a contract assertion[.](#eval-2.sentence-1)
[*Note [1](#eval-note-1)*:
The range and flexibility of available choices of
evaluation semantics depends on the implementation
and need not allow all four evaluation semantics as possibilities[.](#eval-2.sentence-2)
The evaluation semantics can differ
for different evaluations of the same contract assertion,
including evaluations during constant evaluation[.](#eval-2.sentence-3)
— *end note*]
[3](#eval-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7633)
*Recommended practice*: An implementation should provide
the option to translate a program
such that all evaluations of contract assertions use the ignore semantic
as well as
the option to translate a program
such that all evaluations of contract assertions use the enforce semantic[.](#eval-3.sentence-1)
By default,
evaluations of contract assertions should use the enforce semantic[.](#eval-3.sentence-2)
[4](#eval-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7644)
The evaluation of a contract assertion using the ignore semantic has no effect[.](#eval-4.sentence-1)
[*Note [2](#eval-note-2)*:
The predicate is potentially evaluated ([[basic.def.odr]](basic.def.odr "6.3One-definition rule")),
but not evaluated[.](#eval-4.sentence-2)
— *end note*]
[5](#eval-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7651)
The evaluation A of a contract assertion
using a checking semantic
determines the value of the predicate[.](#eval-5.sentence-1)
It is unspecified
whether the predicate is evaluated[.](#eval-5.sentence-2)
Let B be the value that would result from evaluating the predicate[.](#eval-5.sentence-3)
[*Note [3](#eval-note-3)*:
To determine whether a predicate would evaluate
to true or false,
an alternative evaluation
that produces the same value as the predicate
but has no side effects
can occur[.](#eval-5.sentence-4)
[*Example [1](#eval-example-1)*: struct S {mutable int g = 5;} s;void f() pre(( s.g++, false )); // #1void g(){ f(); // Increment of s.g might not occur, even if #1 uses a checking semantic.} — *end example*]
— *end note*]
[6](#eval-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7680)
There is an observable checkpoint ([[intro.abstract]](intro.abstract "4.1.2Abstract machine")) C that happens before A such that any other operation O that happens before A also happens before C[.](#eval-6.sentence-1)
[7](#eval-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7687)
A [*contract violation*](#def:contract_violation "6.11.2Evaluation[basic.contract.eval]") occurs when
- [(7.1)](#eval-7.1)
B is false,
- [(7.2)](#eval-7.2)
the evaluation of the predicate
exits via an exception, or
- [(7.3)](#eval-7.3)
the evaluation of the predicate
is performed in a context that is
manifestly constant-evaluated ([[expr.const]](expr.const "7.7Constant expressions"))
and the predicate
is not a core constant expression[.](#eval-7.sentence-1)
[*Note [4](#eval-note-4)*:
If B is true,
no contract violation occurs and
control flow continues normally
after the point of evaluation of the contract assertion[.](#eval-7.sentence-2)
The evaluation of the predicate
can fail to produce a value
without causing a contract violation,
for example,
by calling longjmp ([[csetjmp.syn]](csetjmp.syn "17.14.3Header <csetjmp> synopsis"))
or terminating the program[.](#eval-7.sentence-3)
— *end note*]
[8](#eval-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7716)
If a contract violation occurs
in a context that is manifestly constant-evaluated ([[expr.const]](expr.const "7.7Constant expressions")),
and the evaluation semantic is
a terminating semantic,
the program is ill-formed[.](#eval-8.sentence-1)
[*Note [5](#eval-note-5)*:
A diagnostic is produced
if the evaluation semantic is observe ([[intro.compliance]](intro.compliance "4.1Implementation compliance"))[.](#eval-8.sentence-2)
— *end note*]
[*Note [6](#eval-note-6)*:
Different evaluation semantics
chosen for the same contract assertion
in different translation units
can result in
violations of the one-definition rule ([[basic.def.odr]](basic.def.odr "6.3One-definition rule"))
when a contract assertion has side effects
that alter the value produced by a constant expression[.](#eval-8.sentence-3)
[*Example [2](#eval-example-2)*: constexpr int f(int i){contract_assert((++const_cast<int&>(i), true)); return i;}inline void g(){int a[f(1)]; // size dependent on the evaluation semantic of contract_assert above} — *end example*]
— *end note*]
[9](#eval-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7752)
When the program is [*contract-terminated*](#def:contract-terminated "6.11.2Evaluation[basic.contract.eval]"),
it isimplementation-defined
(depending on context) whether
- [(9.1)](#eval-9.1)
std::terminate is called,
- [(9.2)](#eval-9.2)
std::abort is called, or
- [(9.3)](#eval-9.3)
execution is terminated[.](#eval-9.sentence-1)
[*Note [7](#eval-note-7)*:
No further execution steps occur ([[intro.progress]](intro.progress "6.10.2.3Forward progress"))[.](#eval-9.3.sentence-2)
— *end note*]
[*Note [8](#eval-note-8)*:
Performing the actions ofstd::terminate or std::abort without actually making a library call
is a conforming implementation of
contract-termination ([[intro.abstract]](intro.abstract "4.1.2Abstract machine"))[.](#eval-9.sentence-2)
— *end note*]
[10](#eval-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7778)
If a contract violation occurs
in a context that is not manifestly constant-evaluated
and the evaluation semantic is quick-enforce,
the program is contract-terminated[.](#eval-10.sentence-1)
[11](#eval-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7786)
If a contract violation occurs
in a context that is not manifestly constant-evaluated
and the evaluation semantic is enforce or observe,
the contract-violation handler ([[basic.contract.handler]](#handler "6.11.3Contract-violation handler"))
is invoked with an lvalue referring to
an object v of type const std::contracts::contract_violation ([[support.contract.violation]](support.contract.violation "17.10.3Class contract_­violation"))
containing information about the contract violation[.](#eval-11.sentence-1)
Storage for v is allocated in an unspecified manner
except as noted in [[basic.stc.dynamic.allocation]](basic.stc.dynamic.allocation "6.8.6.5.2Allocation functions")[.](#eval-11.sentence-2)
The lifetime of v persists for the duration
of the invocation of the contract-violation handler[.](#eval-11.sentence-3)
[12](#eval-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7806)
If the contract violation occurred
because the evaluation of the predicate
exited via an exception,
the contract-violation handler is invoked
from within an active implicit handler
for that exception ([[except.handle]](except.handle "14.4Handling an exception"))[.](#eval-12.sentence-1)
If the contract-violation handler
returns normally
and the evaluation semantic is observe,
that implicit handler
is no longer considered active[.](#eval-12.sentence-2)
[*Note [9](#eval-note-9)*:
The exception can be inspected or rethrown within the contract-violation handler[.](#eval-12.sentence-3)
— *end note*]
[13](#eval-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7823)
If the contract-violation handler
returns normally
and the evaluation semantic is enforce,
the program is contract-terminated;
if violation occurred
as the result of an uncaught exception
from the evaluation of the predicate,
the implicit handler
remains active when contract termination occurs[.](#eval-13.sentence-1)
[14](#eval-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7835)
[*Note [10](#eval-note-10)*:
If the contract-violation handler
returns normally
and the evaluation semantic is observe,
control flow continues normally
after the point of evaluation of the contract assertion[.](#eval-14.sentence-1)
— *end note*]
[15](#eval-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7845)
There is an observable checkpoint ([[intro.abstract]](intro.abstract "4.1.2Abstract machine")) C that happens after the contract-violation handler returns normally
such that any other operation O that happens after the contract-violation handler returns
also happens after C[.](#eval-15.sentence-1)
[16](#eval-16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7852)
[*Note [11](#eval-note-11)*:
The terminating semantics terminate the program
if execution would otherwise continue normally
past a contract violation:
the enforce semantic provides the opportunity to
log information about the contract violation
before terminating the program
or to throw an exception to avoid termination,
and the quick-enforce semantic is intended
to terminate the program as soon as possible
as well as
to minimize the impact of contract checks
on the generated code size[.](#eval-16.sentence-1)
Conversely,
the observe semantic
provides the opportunity to
log information about the contract violation
without having to terminate the program[.](#eval-16.sentence-2)
— *end note*]
[17](#eval-17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7873)
If a contract-violation handler
invoked from the evaluation of a function contract assertion ([[dcl.contract.func]](dcl.contract.func "9.4.1General"))
exits via an exception,
the behavior is as if
the function body exits via that same exception[.](#eval-17.sentence-1)
[*Note [12](#eval-note-12)*:
A [*function-try-block*](except.pre#nt:function-try-block "14.1Preamble[except.pre]") ([[except.pre]](except.pre "14.1Preamble"))
is the function body when present
and thus does not
have an opportunity to catch the exception[.](#eval-17.sentence-2)
If the function
has a non-throwing exception specification,
the function std::terminate is invoked ([[except.terminate]](except.terminate "14.6.2The std::terminate function"))[.](#eval-17.sentence-3)
— *end note*]
[*Note [13](#eval-note-13)*:
If a contract-violation handler
invoked from an [*assertion-statement*](stmt.contract.assert#nt:assertion-statement "8.9Assertion statement[stmt.contract.assert]") ([[stmt.contract.assert]](stmt.contract.assert "8.9Assertion statement"))
exits via an exception,
the search for a handler
continues from the execution of that statement[.](#eval-17.sentence-4)
— *end note*]
[18](#eval-18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7897)
To [*evaluate in sequence*](#def:evaluate_in_sequence "6.11.2Evaluation[basic.contract.eval]") a list R of contract assertions:
- [(18.1)](#eval-18.1)
Construct a list of contract assertions S such that
* [(18.1.1)](#eval-18.1.1)
all elements of R are in S,
* [(18.1.2)](#eval-18.1.2)
each element of R may be repeated animplementation-defined
number of times
within S, and
* [(18.1.3)](#eval-18.1.3)
if a contract assertion A precedes another contract assertion B in R,
then the
first occurrence of A precedes the first occurrence of B in S[.](#eval-18.1.sentence-1)
- [(18.2)](#eval-18.2)
Evaluate each element of S such that,
if a contract assertion A precedes a contract assertion B in S,
then the evaluation of A is sequenced before
the evaluation of B[.](#eval-18.2.sentence-1)
[*Example [3](#eval-example-3)*: void f(int i){contract_assert(i > 0); // #1contract_assert(i < 10); // #2// valid sequence of evaluations: #1 #2// valid sequence of evaluations: #1 #1 #2 #2// valid sequence of evaluations: #1 #2 #1 #2// valid sequence of evaluations: #1 #2 #2 #1// invalid sequence of evaluations: #2 #1} — *end example*]
[19](#eval-19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7945)
*Recommended practice*: An implementation should
provide an option to perform
a specified number of repeated evaluations
for contract assertions[.](#eval-19.sentence-1)
By default,
no repeated evaluations should be performed[.](#eval-19.sentence-2)
### [6.11.3](#handler) Contract-violation handler [[basic.contract.handler]](basic.contract.handler)
[1](#handler-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7956)
The [*contract-violation handler*](#def:contract-violation_handler "6.11.3Contract-violation handler[basic.contract.handler]") of a program is a function named::handle_contract_violation[.](#handler-1.sentence-1)
The contract-violation handler
shall have a single parameter
of type
“lvalue reference to const std::contracts::contract_violation”
and shall return void[.](#handler-1.sentence-2)
The contract-violation handler
may have a non-throwing exception specification[.](#handler-1.sentence-3)
The implementation
shall provide a definition of the contract-violation handler,
called the [*default contract-violation handler*](#def:contract-violation_handler,default "6.11.3Contract-violation handler[basic.contract.handler]")[.](#handler-1.sentence-4)
[*Note [1](#handler-note-1)*:
No declaration
for the default contract-violation handler
is provided by
any standard library header[.](#handler-1.sentence-5)
— *end note*]
[2](#handler-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7979)
*Recommended practice*: The default contract-violation handler
should produce diagnostic output
that suitably formats the most relevant contents
of the std::contracts::contract_violation object,
rate-limited for potentially repeated violations
of observed contract assertions,
and then return normally[.](#handler-2.sentence-1)
[3](#handler-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7989)
It isimplementation-defined
whether the contract-violation handler
is replaceable ([[dcl.fct.def.replace]](dcl.fct.def.replace#term.replaceable.function "9.6.5Replaceable function definitions"))[.](#handler-3.sentence-1)
If the contract-violation handler
is not replaceable,
a declaration of a replacement function for the contract-violation handler
is ill-formed, no diagnostic required[.](#handler-3.sentence-2)

View File

@@ -0,0 +1,389 @@
[basic.contract.eval]
# 6 Basics [[basic]](./#basic)
## 6.11 Contract assertions [[basic.contract]](basic.contract#eval)
### 6.11.2 Evaluation [basic.contract.eval]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7606)
An evaluation of a contract assertion
uses one of the following four [*evaluation semantics*](#def:evaluation_semantics "6.11.2Evaluation[basic.contract.eval]"):[*ignore*](#def:contract_evaluation_semantics,ignore "6.11.2Evaluation[basic.contract.eval]"),[*observe*](#def:contract_evaluation_semantics,observe "6.11.2Evaluation[basic.contract.eval]"),[*enforce*](#def:contract_evaluation_semantics,enforce "6.11.2Evaluation[basic.contract.eval]"), or[*quick-enforce*](#def:contract_evaluation_semantics,quick-enforce "6.11.2Evaluation[basic.contract.eval]")[.](#1.sentence-1)
Observe, enforce, and quick-enforce are [*checking semantics*](#def:contract_evaluation_semantics,checking "6.11.2Evaluation[basic.contract.eval]");
enforce and quick-enforce are [*terminating semantics*](#def:contract_evaluation_semantics,terminating "6.11.2Evaluation[basic.contract.eval]")[.](#1.sentence-2)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7619)
It isimplementation-defined
which evaluation semantic is used
for any given evaluation of a contract assertion[.](#2.sentence-1)
[*Note [1](#note-1)*:
The range and flexibility of available choices of
evaluation semantics depends on the implementation
and need not allow all four evaluation semantics as possibilities[.](#2.sentence-2)
The evaluation semantics can differ
for different evaluations of the same contract assertion,
including evaluations during constant evaluation[.](#2.sentence-3)
— *end note*]
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7633)
*Recommended practice*: An implementation should provide
the option to translate a program
such that all evaluations of contract assertions use the ignore semantic
as well as
the option to translate a program
such that all evaluations of contract assertions use the enforce semantic[.](#3.sentence-1)
By default,
evaluations of contract assertions should use the enforce semantic[.](#3.sentence-2)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7644)
The evaluation of a contract assertion using the ignore semantic has no effect[.](#4.sentence-1)
[*Note [2](#note-2)*:
The predicate is potentially evaluated ([[basic.def.odr]](basic.def.odr "6.3One-definition rule")),
but not evaluated[.](#4.sentence-2)
— *end note*]
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7651)
The evaluation A of a contract assertion
using a checking semantic
determines the value of the predicate[.](#5.sentence-1)
It is unspecified
whether the predicate is evaluated[.](#5.sentence-2)
Let B be the value that would result from evaluating the predicate[.](#5.sentence-3)
[*Note [3](#note-3)*:
To determine whether a predicate would evaluate
to true or false,
an alternative evaluation
that produces the same value as the predicate
but has no side effects
can occur[.](#5.sentence-4)
[*Example [1](#example-1)*: struct S {mutable int g = 5;} s;void f() pre(( s.g++, false )); // #1void g(){ f(); // Increment of s.g might not occur, even if #1 uses a checking semantic.} — *end example*]
— *end note*]
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7680)
There is an observable checkpoint ([[intro.abstract]](intro.abstract "4.1.2Abstract machine")) C that happens before A such that any other operation O that happens before A also happens before C[.](#6.sentence-1)
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7687)
A [*contract violation*](#def:contract_violation "6.11.2Evaluation[basic.contract.eval]") occurs when
- [(7.1)](#7.1)
B is false,
- [(7.2)](#7.2)
the evaluation of the predicate
exits via an exception, or
- [(7.3)](#7.3)
the evaluation of the predicate
is performed in a context that is
manifestly constant-evaluated ([[expr.const]](expr.const "7.7Constant expressions"))
and the predicate
is not a core constant expression[.](#7.sentence-1)
[*Note [4](#note-4)*:
If B is true,
no contract violation occurs and
control flow continues normally
after the point of evaluation of the contract assertion[.](#7.sentence-2)
The evaluation of the predicate
can fail to produce a value
without causing a contract violation,
for example,
by calling longjmp ([[csetjmp.syn]](csetjmp.syn "17.14.3Header <csetjmp> synopsis"))
or terminating the program[.](#7.sentence-3)
— *end note*]
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7716)
If a contract violation occurs
in a context that is manifestly constant-evaluated ([[expr.const]](expr.const "7.7Constant expressions")),
and the evaluation semantic is
a terminating semantic,
the program is ill-formed[.](#8.sentence-1)
[*Note [5](#note-5)*:
A diagnostic is produced
if the evaluation semantic is observe ([[intro.compliance]](intro.compliance "4.1Implementation compliance"))[.](#8.sentence-2)
— *end note*]
[*Note [6](#note-6)*:
Different evaluation semantics
chosen for the same contract assertion
in different translation units
can result in
violations of the one-definition rule ([[basic.def.odr]](basic.def.odr "6.3One-definition rule"))
when a contract assertion has side effects
that alter the value produced by a constant expression[.](#8.sentence-3)
[*Example [2](#example-2)*: constexpr int f(int i){contract_assert((++const_cast<int&>(i), true)); return i;}inline void g(){int a[f(1)]; // size dependent on the evaluation semantic of contract_assert above} — *end example*]
— *end note*]
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7752)
When the program is [*contract-terminated*](#def:contract-terminated "6.11.2Evaluation[basic.contract.eval]"),
it isimplementation-defined
(depending on context) whether
- [(9.1)](#9.1)
std::terminate is called,
- [(9.2)](#9.2)
std::abort is called, or
- [(9.3)](#9.3)
execution is terminated[.](#9.sentence-1)
[*Note [7](#note-7)*:
No further execution steps occur ([[intro.progress]](intro.progress "6.10.2.3Forward progress"))[.](#9.3.sentence-2)
— *end note*]
[*Note [8](#note-8)*:
Performing the actions ofstd::terminate or std::abort without actually making a library call
is a conforming implementation of
contract-termination ([[intro.abstract]](intro.abstract "4.1.2Abstract machine"))[.](#9.sentence-2)
— *end note*]
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7778)
If a contract violation occurs
in a context that is not manifestly constant-evaluated
and the evaluation semantic is quick-enforce,
the program is contract-terminated[.](#10.sentence-1)
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7786)
If a contract violation occurs
in a context that is not manifestly constant-evaluated
and the evaluation semantic is enforce or observe,
the contract-violation handler ([[basic.contract.handler]](basic.contract.handler "6.11.3Contract-violation handler"))
is invoked with an lvalue referring to
an object v of type const std::contracts::contract_violation ([[support.contract.violation]](support.contract.violation "17.10.3Class contract_­violation"))
containing information about the contract violation[.](#11.sentence-1)
Storage for v is allocated in an unspecified manner
except as noted in [[basic.stc.dynamic.allocation]](basic.stc.dynamic.allocation "6.8.6.5.2Allocation functions")[.](#11.sentence-2)
The lifetime of v persists for the duration
of the invocation of the contract-violation handler[.](#11.sentence-3)
[12](#12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7806)
If the contract violation occurred
because the evaluation of the predicate
exited via an exception,
the contract-violation handler is invoked
from within an active implicit handler
for that exception ([[except.handle]](except.handle "14.4Handling an exception"))[.](#12.sentence-1)
If the contract-violation handler
returns normally
and the evaluation semantic is observe,
that implicit handler
is no longer considered active[.](#12.sentence-2)
[*Note [9](#note-9)*:
The exception can be inspected or rethrown within the contract-violation handler[.](#12.sentence-3)
— *end note*]
[13](#13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7823)
If the contract-violation handler
returns normally
and the evaluation semantic is enforce,
the program is contract-terminated;
if violation occurred
as the result of an uncaught exception
from the evaluation of the predicate,
the implicit handler
remains active when contract termination occurs[.](#13.sentence-1)
[14](#14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7835)
[*Note [10](#note-10)*:
If the contract-violation handler
returns normally
and the evaluation semantic is observe,
control flow continues normally
after the point of evaluation of the contract assertion[.](#14.sentence-1)
— *end note*]
[15](#15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7845)
There is an observable checkpoint ([[intro.abstract]](intro.abstract "4.1.2Abstract machine")) C that happens after the contract-violation handler returns normally
such that any other operation O that happens after the contract-violation handler returns
also happens after C[.](#15.sentence-1)
[16](#16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7852)
[*Note [11](#note-11)*:
The terminating semantics terminate the program
if execution would otherwise continue normally
past a contract violation:
the enforce semantic provides the opportunity to
log information about the contract violation
before terminating the program
or to throw an exception to avoid termination,
and the quick-enforce semantic is intended
to terminate the program as soon as possible
as well as
to minimize the impact of contract checks
on the generated code size[.](#16.sentence-1)
Conversely,
the observe semantic
provides the opportunity to
log information about the contract violation
without having to terminate the program[.](#16.sentence-2)
— *end note*]
[17](#17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7873)
If a contract-violation handler
invoked from the evaluation of a function contract assertion ([[dcl.contract.func]](dcl.contract.func "9.4.1General"))
exits via an exception,
the behavior is as if
the function body exits via that same exception[.](#17.sentence-1)
[*Note [12](#note-12)*:
A [*function-try-block*](except.pre#nt:function-try-block "14.1Preamble[except.pre]") ([[except.pre]](except.pre "14.1Preamble"))
is the function body when present
and thus does not
have an opportunity to catch the exception[.](#17.sentence-2)
If the function
has a non-throwing exception specification,
the function std::terminate is invoked ([[except.terminate]](except.terminate "14.6.2The std::terminate function"))[.](#17.sentence-3)
— *end note*]
[*Note [13](#note-13)*:
If a contract-violation handler
invoked from an [*assertion-statement*](stmt.contract.assert#nt:assertion-statement "8.9Assertion statement[stmt.contract.assert]") ([[stmt.contract.assert]](stmt.contract.assert "8.9Assertion statement"))
exits via an exception,
the search for a handler
continues from the execution of that statement[.](#17.sentence-4)
— *end note*]
[18](#18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7897)
To [*evaluate in sequence*](#def:evaluate_in_sequence "6.11.2Evaluation[basic.contract.eval]") a list R of contract assertions:
- [(18.1)](#18.1)
Construct a list of contract assertions S such that
* [(18.1.1)](#18.1.1)
all elements of R are in S,
* [(18.1.2)](#18.1.2)
each element of R may be repeated animplementation-defined
number of times
within S, and
* [(18.1.3)](#18.1.3)
if a contract assertion A precedes another contract assertion B in R,
then the
first occurrence of A precedes the first occurrence of B in S[.](#18.1.sentence-1)
- [(18.2)](#18.2)
Evaluate each element of S such that,
if a contract assertion A precedes a contract assertion B in S,
then the evaluation of A is sequenced before
the evaluation of B[.](#18.2.sentence-1)
[*Example [3](#example-3)*: void f(int i){contract_assert(i > 0); // #1contract_assert(i < 10); // #2// valid sequence of evaluations: #1 #2// valid sequence of evaluations: #1 #1 #2 #2// valid sequence of evaluations: #1 #2 #1 #2// valid sequence of evaluations: #1 #2 #2 #1// invalid sequence of evaluations: #2 #1} — *end example*]
[19](#19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7945)
*Recommended practice*: An implementation should
provide an option to perform
a specified number of repeated evaluations
for contract assertions[.](#19.sentence-1)
By default,
no repeated evaluations should be performed[.](#19.sentence-2)

View File

@@ -0,0 +1,55 @@
[basic.contract.general]
# 6 Basics [[basic]](./#basic)
## 6.11 Contract assertions [[basic.contract]](basic.contract#general)
### 6.11.1 General [basic.contract.general]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7567)
[*Contract assertions*](#def:contract_assertion "6.11.1General[basic.contract.general]") allow the programmer to specify
properties of the state of the program
that are expected to hold at
certain points during execution[.](#1.sentence-1)
Contract assertions are introduced by[*precondition-specifier*](dcl.contract.func#nt:precondition-specifier "9.4.1General[dcl.contract.func]")*s*,[*postcondition-specifier*](dcl.contract.func#nt:postcondition-specifier "9.4.1General[dcl.contract.func]")*s* ([[dcl.contract.func]](dcl.contract.func "9.4.1General")), and[*assertion-statement*](stmt.contract.assert#nt:assertion-statement "8.9Assertion statement[stmt.contract.assert]")*s* ([[stmt.contract.assert]](stmt.contract.assert "8.9Assertion statement"))[.](#1.sentence-2)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7578)
Each contract assertion has a [*contract-assertion predicate*](#def:predicate,contract-assertion "6.11.1General[basic.contract.general]"),
which is an expression of type bool[.](#2.sentence-1)
[*Note [1](#note-1)*:
The value of the predicate is used to identify program states that are
expected[.](#2.sentence-2)
— *end note*]
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7587)
An invocation of the macro va_start ([[cstdarg.syn]](cstdarg.syn "17.14.2Header <cstdarg> synopsis"))
shall not be a subexpression
of the predicate of a contract assertion,
no diagnostic required[.](#3.sentence-1)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7593)
[*Note [2](#note-2)*:
Within the predicate of a contract assertion,[*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1General[expr.prim.id.general]")*s* referring to
variables declared outside the contract assertion
are const ([[expr.prim.id.unqual]](expr.prim.id.unqual "7.5.5.2Unqualified names")),this is a pointer to const ([[expr.prim.this]](expr.prim.this "7.5.3This")),
and the result object can be named
if a [*result-name-introducer*](dcl.contract.res#nt:result-name-introducer "9.4.2Referring to the result object[dcl.contract.res]") ([[dcl.contract.res]](dcl.contract.res "9.4.2Referring to the result object")) has been specified[.](#4.sentence-1)
— *end note*]

View File

@@ -0,0 +1,60 @@
[basic.contract.handler]
# 6 Basics [[basic]](./#basic)
## 6.11 Contract assertions [[basic.contract]](basic.contract#handler)
### 6.11.3 Contract-violation handler [basic.contract.handler]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7956)
The [*contract-violation handler*](#def:contract-violation_handler "6.11.3Contract-violation handler[basic.contract.handler]") of a program is a function named::handle_contract_violation[.](#1.sentence-1)
The contract-violation handler
shall have a single parameter
of type
“lvalue reference to const std::contracts::contract_violation”
and shall return void[.](#1.sentence-2)
The contract-violation handler
may have a non-throwing exception specification[.](#1.sentence-3)
The implementation
shall provide a definition of the contract-violation handler,
called the [*default contract-violation handler*](#def:contract-violation_handler,default "6.11.3Contract-violation handler[basic.contract.handler]")[.](#1.sentence-4)
[*Note [1](#note-1)*:
No declaration
for the default contract-violation handler
is provided by
any standard library header[.](#1.sentence-5)
— *end note*]
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7979)
*Recommended practice*: The default contract-violation handler
should produce diagnostic output
that suitably formats the most relevant contents
of the std::contracts::contract_violation object,
rate-limited for potentially repeated violations
of observed contract assertions,
and then return normally[.](#2.sentence-1)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7989)
It isimplementation-defined
whether the contract-violation handler
is replaceable ([[dcl.fct.def.replace]](dcl.fct.def.replace#term.replaceable.function "9.6.5Replaceable function definitions"))[.](#3.sentence-1)
If the contract-violation handler
is not replaceable,
a declaration of a replacement function for the contract-violation handler
is ill-formed, no diagnostic required[.](#3.sentence-2)

214
cppdraft/basic/def.md Normal file
View File

@@ -0,0 +1,214 @@
[basic.def]
# 6 Basics [[basic]](./#basic)
## 6.2 Declarations and definitions [basic.def]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L166)
A declaration ([[basic.pre]](basic.pre "6.1Preamble")) may (re)introduce
one or more names and/or entities into a translation
unit[.](#1.sentence-1)
If so, the
declaration specifies the interpretation and semantic properties of these names[.](#1.sentence-2)
A declaration of an entity X is
a redeclaration of X if another declaration of X is reachable from it ([[module.reach]](module.reach "10.7Reachability"));
otherwise, it is a [*first declaration*](#def:declaration,first "6.2Declarations and definitions[basic.def]")[.](#1.sentence-3)
A declaration may also have effects including:
- [(1.1)](#1.1)
a static assertion ([[dcl.pre]](dcl.pre "9.1Preamble")),
- [(1.2)](#1.2)
controlling template instantiation ([[temp.explicit]](temp.explicit "13.9.3Explicit instantiation")),
- [(1.3)](#1.3)
guiding template argument deduction for constructors ([[temp.deduct.guide]](temp.deduct.guide "13.7.2.3Deduction guides")),
- [(1.4)](#1.4)
use of [attributes](dcl.attr "9.13Attributes[dcl.attr]"), and
- [(1.5)](#1.5)
nothing (in the case of an [*empty-declaration*](dcl.pre#nt:empty-declaration "9.1Preamble[dcl.pre]"))[.](#1.sentence-4)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L188)
Each entity declared by a [*declaration*](dcl.pre#nt:declaration "9.1Preamble[dcl.pre]") is
also [*defined*](#def:define "6.2Declarations and definitions[basic.def]") by that declaration unless:
- [(2.1)](#2.1)
it declares a function
without specifying the function's body ([[dcl.fct.def]](dcl.fct.def "9.6Function definitions")),
- [(2.2)](#2.2)
it contains
theextern specifier ([[dcl.stc]](dcl.stc "9.2.2Storage class specifiers")) or a[*linkage-specification*](dcl.link#nt:linkage-specification "9.12Linkage specifications[dcl.link]")[15](#footnote-15 "Appearing inside the brace-enclosed declaration-seq in a linkage-specification does not affect whether a declaration is a definition.") ([[dcl.link]](dcl.link "9.12Linkage specifications"))
and neither an [*initializer*](dcl.init.general#nt:initializer "9.5.1General[dcl.init.general]") nor a[*function-body*](dcl.fct.def.general#nt:function-body "9.6.1General[dcl.fct.def.general]"),
- [(2.3)](#2.3)
it declares a non-inline static data member in a class
definition ([[class.mem]](class.mem "11.4Class members"), [[class.static]](class.static "11.4.9Static members")),
- [(2.4)](#2.4)
it declares a static data member outside a class definition
and the variable was defined within the class with the constexpr specifier ([[class.static.data]](class.static.data "11.4.9.3Static data members")) (this usage is deprecated; see [[depr.static.constexpr]](depr.static.constexpr "D.7Redeclaration of static constexpr data members")),
- [(2.5)](#2.5)
it is an [*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5Elaborated type specifiers[dcl.type.elab]") ([[class.name]](class.name "11.3Class names")),
- [(2.6)](#2.6)
it is an[*opaque-enum-declaration*](dcl.enum#nt:opaque-enum-declaration "9.8.1Enumeration declarations[dcl.enum]") ([[dcl.enum]](dcl.enum "9.8.1Enumeration declarations")),
- [(2.7)](#2.7)
it is a[*template-parameter*](temp.param#nt:template-parameter "13.2Template parameters[temp.param]") ([[temp.param]](temp.param "13.2Template parameters")),
- [(2.8)](#2.8)
it is a[*parameter-declaration*](dcl.fct#nt:parameter-declaration "9.3.4.6Functions[dcl.fct]") ([[dcl.fct]](dcl.fct "9.3.4.6Functions")) in a functiondeclarator that is not the [*declarator*](dcl.decl.general#nt:declarator "9.3.1General[dcl.decl.general]") of a[*function-definition*](dcl.fct.def.general#nt:function-definition "9.6.1General[dcl.fct.def.general]"),
- [(2.9)](#2.9)
it is atypedef declaration ([[dcl.typedef]](dcl.typedef "9.2.4The typedef specifier")),
- [(2.10)](#2.10)
it is
an [*alias-declaration*](dcl.pre#nt:alias-declaration "9.1Preamble[dcl.pre]") ([[dcl.typedef]](dcl.typedef "9.2.4The typedef specifier")),
- [(2.11)](#2.11)
it is
a [*namespace-alias-definition*](namespace.alias#nt:namespace-alias-definition "9.9.3Namespace alias[namespace.alias]") ([[namespace.alias]](namespace.alias "9.9.3Namespace alias")),
- [(2.12)](#2.12)
it is
a [*using-declaration*](namespace.udecl#nt:using-declaration "9.10The using declaration[namespace.udecl]") ([[namespace.udecl]](namespace.udecl "9.10The using declaration")),
- [(2.13)](#2.13)
it is
a [*deduction-guide*](temp.deduct.guide#nt:deduction-guide "13.7.2.3Deduction guides[temp.deduct.guide]") ([[temp.deduct.guide]](temp.deduct.guide "13.7.2.3Deduction guides")),
- [(2.14)](#2.14)
it is
a [*static_assert-declaration*](dcl.pre#nt:static_assert-declaration "9.1Preamble[dcl.pre]") ([[dcl.pre]](dcl.pre "9.1Preamble")),
- [(2.15)](#2.15)
it is
a [*consteval-block-declaration*](dcl.pre#nt:consteval-block-declaration "9.1Preamble[dcl.pre]"),
- [(2.16)](#2.16)
it is an[*attribute-declaration*](dcl.pre#nt:attribute-declaration "9.1Preamble[dcl.pre]") ([[dcl.pre]](dcl.pre "9.1Preamble")),
- [(2.17)](#2.17)
it is an[*empty-declaration*](dcl.pre#nt:empty-declaration "9.1Preamble[dcl.pre]") ([[dcl.pre]](dcl.pre "9.1Preamble")),
- [(2.18)](#2.18)
it is
a [*using-directive*](namespace.udir#nt:using-directive "9.9.4Using namespace directive[namespace.udir]") ([[namespace.udir]](namespace.udir "9.9.4Using namespace directive")),
- [(2.19)](#2.19)
it is
a [*using-enum-declaration*](enum.udecl#nt:using-enum-declaration "9.8.2The using enum declaration[enum.udecl]") ([[enum.udecl]](enum.udecl "9.8.2The using enum declaration")),
- [(2.20)](#2.20)
it is
a [*template-declaration*](temp.pre#nt:template-declaration "13.1Preamble[temp.pre]") ([[temp.pre]](temp.pre "13.1Preamble"))
whose [*template-head*](temp.pre#nt:template-head "13.1Preamble[temp.pre]") is not followed by
either a [*concept-definition*](temp.concept#nt:concept-definition "13.7.9Concept definitions[temp.concept]") or a [*declaration*](dcl.pre#nt:declaration "9.1Preamble[dcl.pre]") that defines a function, a class, a variable, or a static data member,
- [(2.21)](#2.21)
it is
an explicit instantiation declaration ([[temp.explicit]](temp.explicit "13.9.3Explicit instantiation")), or
- [(2.22)](#2.22)
it is
an [explicit specialization](temp.expl.spec "13.9.4Explicit specialization[temp.expl.spec]") whose[*declaration*](dcl.pre#nt:declaration "9.1Preamble[dcl.pre]") is not a definition[.](#2.sentence-1)
A declaration is said to be a [*definition*](#def:definition "6.2Declarations and definitions[basic.def]") of each entity that it defines[.](#2.sentence-2)
[*Example [1](#example-1)*:
All but one of the following are definitions:int a; // defines aextern const int c = 1; // defines cint f(int x) { return x+a; } // defines f and defines xstruct S { int a; int b; }; // defines S, S::a, and S::bstruct X { // defines Xint x; // defines non-static data member xstatic int y; // declares static data member y X(): x(0) { } // defines a constructor of X};int X::y = 1; // defines X::yenum { up, down }; // defines up and downnamespace N { int d; } // defines N and N::d X anX; // defines anX whereas these are just declarations:extern int a; // declares aextern const int c; // declares cint f(int); // declares fstruct S; // declares Stypedef int Int; // declares Intnamespace N1 = N; // declares N1extern X anotherX; // declares anotherXusing N::d; // declares d
— *end example*]
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L304)
[*Note [1](#note-1)*:
In some circumstances, C++ implementations implicitly define the
default constructor ([[class.default.ctor]](class.default.ctor "11.4.5.2Default constructors")),
copy constructor, move constructor ([[class.copy.ctor]](class.copy.ctor "11.4.5.3Copy/move constructors")),
copy assignment operator, move assignment operator ([[class.copy.assign]](class.copy.assign "11.4.6Copy/move assignment operator")),
or [destructor](class.dtor "11.4.7Destructors[class.dtor]") member functions[.](#3.sentence-1)
— *end note*]
[*Example [2](#example-2)*:
Given#include <string>struct C { std::string s; // std::string is the standard library class ([[string.classes]](string.classes "27.4String classes"))};
int main() { C a;
C b = a;
b = a;} the implementation will implicitly define functions to make the
definition of C equivalent tostruct C { std::string s;
C() : s() { } C(const C& x): s(x.s) { } C(C&& x): s(static_cast<std::string&&>(x.s)) { }*//* : s(std::move(x.s)) { } C& operator=(const C& x) { s = x.s; return *this; } C& operator=(C&& x) { s = static_cast<std::string&&>(x.s); return *this; }*//* { s = std::move(x.s); return *this; }~C() { }};
— *end example*]
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L345)
[*Note [2](#note-2)*:
A class name can also be implicitly declared by an[*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5Elaborated type specifiers[dcl.type.elab]") ([[dcl.type.elab]](dcl.type.elab "9.2.9.5Elaborated type specifiers"))[.](#4.sentence-1)
— *end note*]
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L351)
In the definition of an object,
the type of that object shall not be
an incomplete type ([[basic.types.general]](basic.types.general#term.incomplete.type "6.9.1General")),
an abstract class type ([[class.abstract]](class.abstract "11.7.4Abstract classes")), or
a (possibly multidimensional) array thereof[.](#5.sentence-1)
[15)](#footnote-15)[15)](#footnoteref-15)
Appearing inside the brace-enclosed[*declaration-seq*](dcl.pre#nt:declaration-seq "9.1Preamble[dcl.pre]") in a [*linkage-specification*](dcl.link#nt:linkage-specification "9.12Linkage specifications[dcl.link]") does
not affect whether a declaration is a definition[.](#footnote-15.sentence-1)

669
cppdraft/basic/def/odr.md Normal file
View File

@@ -0,0 +1,669 @@
[basic.def.odr]
# 6 Basics [[basic]](./#basic)
## 6.3 One-definition rule [basic.def.odr]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L366)
Each of the following is termed a [*definable item*](#def:item,definable "6.3One-definition rule[basic.def.odr]"):
- [(1.1)](#1.1)
a class type ([[class]](class "11Classes")),
- [(1.2)](#1.2)
an enumeration type ([[dcl.enum]](dcl.enum "9.8.1Enumeration declarations")),
- [(1.3)](#1.3)
a function ([[dcl.fct]](dcl.fct "9.3.4.6Functions")),
- [(1.4)](#1.4)
a variable ([[basic.pre]](basic.pre "6.1Preamble")),
- [(1.5)](#1.5)
a templated entity ([[temp.pre]](temp.pre "13.1Preamble")),
- [(1.6)](#1.6)
a default argument for a parameter
(for a function in a given scope) ([[dcl.fct.default]](dcl.fct.default "9.3.4.7Default arguments")), or
- [(1.7)](#1.7)
a default template argument ([[temp.param]](temp.param "13.2Template parameters"))[.](#1.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L379)
No translation unit shall contain more than one definition of any
definable item[.](#2.sentence-1)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L383)
An expression or conversion is [*potentially evaluated*](#def:potentially_evaluated "6.3One-definition rule[basic.def.odr]") unless it is
an unevaluated operand ([[expr.context]](expr.context "7.2.3Context dependence")),
a subexpression thereof, or
a conversion in an initialization or conversion sequence in such a context[.](#3.sentence-1)
The set of [*potential results*](#def:potential_results "6.3One-definition rule[basic.def.odr]") of an expression E is
defined as follows:
- [(3.1)](#3.1)
If E is
an [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1General[expr.prim.id.general]") ([[expr.prim.id]](expr.prim.id "7.5.5Names")) or
a [*splice-expression*](expr.prim.splice#nt:splice-expression "7.5.9Expression splicing[expr.prim.splice]") ([[expr.prim.splice]](expr.prim.splice "7.5.9Expression splicing")), the set
contains only E[.](#3.1.sentence-1)
- [(3.2)](#3.2)
If E is a [subscripting](expr.sub "7.6.1.2Subscripting[expr.sub]") operation with
an array operand, the set contains the potential results of that operand[.](#3.2.sentence-1)
- [(3.3)](#3.3)
If E is a class member access
expression ([[expr.ref]](expr.ref "7.6.1.5Class member access")) of the formE1 . templateopt E2 naming a non-static data member,
the set contains the potential results of E1[.](#3.3.sentence-1)
- [(3.4)](#3.4)
If E is a class member access expression
naming a static data member,
the set contains the [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1General[expr.prim.id.general]") designating the data member[.](#3.4.sentence-1)
- [(3.5)](#3.5)
If E is a [pointer-to-member expression](expr.mptr.oper "7.6.4Pointer-to-member operators[expr.mptr.oper]") of the formE1 .* E2,
the set contains the potential results of E1[.](#3.5.sentence-1)
- [(3.6)](#3.6)
If E has the form (E1), the set contains the
potential results of E1[.](#3.6.sentence-1)
- [(3.7)](#3.7)
If E is a glvalue [conditional expression](expr.cond "7.6.16Conditional operator[expr.cond]"),
the set is the union of the sets of
potential results of the second and third operands[.](#3.7.sentence-1)
- [(3.8)](#3.8)
If E is a [comma expression](expr.comma "7.6.20Comma operator[expr.comma]"), the set
contains the potential results of the right operand[.](#3.8.sentence-1)
- [(3.9)](#3.9)
Otherwise, the set is empty[.](#3.9.sentence-1)
[*Note [1](#note-1)*:
This set is a (possibly-empty) set of[*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1General[expr.prim.id.general]")*s* and [*splice-expression*](expr.prim.splice#nt:splice-expression "7.5.9Expression splicing[expr.prim.splice]")*s*,
each of which is either E or a subexpression of E[.](#3.sentence-3)
[*Example [1](#example-1)*:
In the following example, the set of potential results of the initializer
of n contains the first S::x subexpression, but not the secondS::x subexpression[.](#3.sentence-4)
The set of potential results of the initializer of o contains
the subexpression [:^^S::x:][.](#3.sentence-5)
struct S { static const int x = 0; };const int &f(const int &r);int n = b ? (1, S::x) // S::x is not odr-used here: f(S::x); // S::x is odr-used here, so a definition is requiredint o = [:^^S::x:]; — *end example*]
— *end note*]
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L438)
A function is [*named by*](#def:function,named_by_expression_or_conversion "6.3One-definition rule[basic.def.odr]") an expression or conversion as follows:
- [(4.1)](#4.1)
A function is named by an expression or conversion
if it is the selected member
of an overload set ([[basic.lookup]](basic.lookup "6.5Name lookup"), [[over.match]](over.match "12.2Overload resolution"), [[over.over]](over.over "12.3Address of an overload set"))
in an overload resolution performed
as part of forming that expression or conversion,
and either
it is not a pure virtual function or
the expression is an [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1General[expr.prim.id.general]") naming the function with
an explicitly qualified name
that does not form a pointer to member ([[expr.unary.op]](expr.unary.op "7.6.2.2Unary operators"))[.](#4.1.sentence-1)
[*Note [2](#note-2)*:
This covers
taking the address of functions ([[conv.func]](conv.func "7.3.4Function-to-pointer conversion"), [[expr.unary.op]](expr.unary.op "7.6.2.2Unary operators")),
calls to named functions ([[expr.call]](expr.call "7.6.1.3Function call")),
operator overloading ([[over]](over "12Overloading")),
user-defined conversions ([[class.conv.fct]](class.conv.fct "11.4.8.3Conversion functions")),
allocation functions for [*new-expression*](expr.new#nt:new-expression "7.6.2.8New[expr.new]")*s* ([[expr.new]](expr.new "7.6.2.8New")), as well as
non-default initialization ([[dcl.init]](dcl.init "9.5Initializers"))[.](#4.1.sentence-2)
A constructor selected to copy or move an object of class type
is considered to be named by an expression or conversion
even if the call is actually elided by the implementation ([[class.copy.elision]](class.copy.elision "11.9.6Copy/move elision"))[.](#4.1.sentence-3)
— *end note*]
- [(4.2)](#4.2)
A deallocation function for a class
is named by a [*new-expression*](expr.new#nt:new-expression "7.6.2.8New[expr.new]") if it is the single matching deallocation function
for the allocation function selected by overload resolution,
as specified in [[expr.new]](expr.new "7.6.2.8New")[.](#4.2.sentence-1)
- [(4.3)](#4.3)
A deallocation function for a class
is named by a [*delete-expression*](expr.delete#nt:delete-expression "7.6.2.9Delete[expr.delete]") if it is the selected usual deallocation function
as specified in [[expr.delete]](expr.delete "7.6.2.9Delete") and [[class.free]](class.free "11.4.11Allocation and deallocation functions")[.](#4.3.sentence-1)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L478)
A variable is named by an expression
if the expression is an [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1General[expr.prim.id.general]") or[*splice-expression*](expr.prim.splice#nt:splice-expression "7.5.9Expression splicing[expr.prim.splice]") ([[expr.prim.splice]](expr.prim.splice "7.5.9Expression splicing"))
that designates it[.](#5.sentence-1)
A variable x that is named by a
potentially-evaluated expression N that appears at a point P is [*odr-used*](#def:odr-use "6.3One-definition rule[basic.def.odr]") by N unless
- [(5.1)](#5.1)
x is a reference
that is usable in constant expressions at P ([[expr.const]](expr.const "7.7Constant expressions")) or
- [(5.2)](#5.2)
N is an element of the set of potential results of an expression E, where
* [(5.2.1)](#5.2.1)
E is a discarded-value expression ([[expr.context]](expr.context "7.2.3Context dependence"))
to which the lvalue-to-rvalue conversion is not applied or
* [(5.2.2)](#5.2.2)
x is a non-volatile object
that is usable in constant expressions at P and
has no mutable subobjects and
+
[(5.2.2.1)](#5.2.2.1)
E is a class member access expression ([[expr.ref]](expr.ref "7.6.1.5Class member access"))
naming a non-static data member of reference type and
whose object expression has non-volatile-qualified type or
+
[(5.2.2.2)](#5.2.2.2)
the lvalue-to-rvalue conversion ([[conv.lval]](conv.lval "7.3.2Lvalue-to-rvalue conversion")) is applied to E andE has non-volatile-qualified non-class type
[*Example [2](#example-2)*: int f(int);int g(int&);struct A {int x;};struct B {int& r;};int h(bool cond) {constexpr A a = {1}; constexpr const volatile A& r = a; // odr-uses aint _ = f(cond ? a.x : r.x); // does not odr-use a or rint x, y; constexpr B b1 = {x}, b2 = {y}; // odr-uses x and yint _ = g(cond ? b1.r : b2.r); // does not odr-use b1 or b2int _ = ((cond ? x : y), 0); // does not odr-use x or yreturn [] {return b1.r; // error: b1 is odr-used here because the object// referred to by b1.r is not constexpr-referenceable here}();} — *end example*]
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L539)
A structured binding is named by an expression
if that expression is either an [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1General[expr.prim.id.general]") or
a [*splice-expression*](expr.prim.splice#nt:splice-expression "7.5.9Expression splicing[expr.prim.splice]") that designates that structured binding[.](#6.sentence-1)
A structured binding is odr-used
if it is named by a potentially-evaluated expression[.](#6.sentence-2)
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L547)
*this is odr-used if this appears as a potentially-evaluated expression
(including as the result of any implicit transformation to
a class member access expression ([[expr.prim.id.general]](expr.prim.id.general "7.5.5.1General")))[.](#7.sentence-1)
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L552)
A virtual member
function is odr-used if it is not pure[.](#8.sentence-1)
A function is odr-used if it is named by
a potentially-evaluated expression or conversion[.](#8.sentence-2)
A non-placement allocation or deallocation
function for a class is odr-used by the definition of a constructor of that
class[.](#8.sentence-3)
A non-placement deallocation function for a class is odr-used by the
definition of the destructor of that class, or by being selected by the
lookup at the point of definition of a virtual
destructor ([[class.dtor]](class.dtor "11.4.7Destructors"))[.](#8.sentence-4)[16](#footnote-16 "An implementation is not required to call allocation and deallocation functions from constructors or destructors; however, this is a permissible implementation technique.")
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L570)
An assignment operator function in a class is odr-used by an
implicitly-defined
copy assignment or move assignment function for another class as specified
in [[class.copy.assign]](class.copy.assign "11.4.6Copy/move assignment operator")[.](#9.sentence-1)
A constructor for a class is odr-used as specified
in [[dcl.init]](dcl.init "9.5Initializers")[.](#9.sentence-2)
A destructor for a class is odr-used if it is[potentially invoked](class.dtor#def:potentially_invoked "11.4.7Destructors[class.dtor]")[.](#9.sentence-3)
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L579)
A local entity ([[basic.pre]](basic.pre "6.1Preamble"))
is [*odr-usable*](#def:odr-usable "6.3One-definition rule[basic.def.odr]") in a scope ([[basic.scope.scope]](basic.scope.scope "6.4.1General")) if
- [(10.1)](#10.1)
either the local entity is not *this, or
an enclosing class or non-lambda function parameter scope exists and,
if the innermost such scope is a function parameter scope,
it corresponds to a non-static member function, and
- [(10.2)](#10.2)
for each intervening scope ([[basic.scope.scope]](basic.scope.scope "6.4.1General"))
between the point at which the entity is introduced and the scope
(where *this is considered to be introduced
within the innermost enclosing class or non-lambda function definition scope),
either
* [(10.2.1)](#10.2.1)
the intervening scope is a block scope,
* [(10.2.2)](#10.2.2)
the intervening scope is a contract-assertion scope ([[basic.scope.contract]](basic.scope.contract "6.4.10Contract-assertion scope")),
* [(10.2.3)](#10.2.3)
the intervening scope is the function parameter scope of
a [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1General[expr.prim.lambda.general]") or [*requires-expression*](expr.prim.req.general#nt:requires-expression "7.5.8.1General[expr.prim.req.general]"), or
* [(10.2.4)](#10.2.4)
the intervening scope is the lambda scope of
a [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1General[expr.prim.lambda.general]") that has a [*simple-capture*](expr.prim.lambda.capture#nt:simple-capture "7.5.6.3Captures[expr.prim.lambda.capture]") naming the entity or has a [*capture-default*](expr.prim.lambda.capture#nt:capture-default "7.5.6.3Captures[expr.prim.lambda.capture]"), and
the block scope of the [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1General[expr.prim.lambda.general]") is also an intervening scope[.](#10.sentence-1)
If a local entity is odr-used
in a scope in which it is not odr-usable,
the program is ill-formed[.](#10.sentence-2)
[*Example [3](#example-3)*: void f(int n) {[] { n = 1; }; // error: n is not odr-usable due to intervening lambda-expressionstruct A {void f() { n = 2; } // error: n is not odr-usable due to intervening function definition scope}; void g(int = n); // error: n is not odr-usable due to intervening function parameter scope[=](int k = n) {}; // error: n is not odr-usable due to being// outside the block scope of the [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1General[expr.prim.lambda.general]")[&] { [n]{ return n; }; }; // OK} — *end example*]
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L625)
[*Example [4](#example-4)*: void g() {constexpr int x = 1; auto lambda = [] <typename T, int = ((T)x, 0)> {}; // OK lambda.operator()<int, 1>(); // OK, does not consider x at all lambda.operator()<int>(); // OK, does not odr-use x lambda.operator()<const int&>(); // error: odr-uses x from a context where x is not odr-usable}void h() {constexpr int x = 1; auto lambda = [] <typename T> { (T)x; }; // OK lambda.operator()<int>(); // OK, does not odr-use x lambda.operator()<void>(); // OK, does not odr-use x lambda.operator()<const int&>(); // error: odr-uses x from a context where x is not odr-usable} — *end example*]
[12](#12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L646)
Every program shall contain at least one definition of every
function or variable that is odr-used in that program
outside of a [discarded statement](stmt.if#def:discarded_statement "8.5.2The if statement[stmt.if]"); no diagnostic required[.](#12.sentence-1)
The definition can appear explicitly in the program, it can be found in
the standard or a user-defined library, or (when appropriate) it is
implicitly defined (see [[class.default.ctor]](class.default.ctor "11.4.5.2Default constructors"), [[class.copy.ctor]](class.copy.ctor "11.4.5.3Copy/move constructors"),[[class.dtor]](class.dtor "11.4.7Destructors"), and [[class.copy.assign]](class.copy.assign "11.4.6Copy/move assignment operator"))[.](#12.sentence-2)
[*Example [5](#example-5)*: auto f() {struct A {}; return A{};}decltype(f()) g();auto x = g();
A program containing this translation unit is ill-formed
because g is odr-used but not defined,
and cannot be defined in any other translation unit
because the local class A cannot be named outside this
translation unit[.](#12.sentence-3)
— *end example*]
[13](#13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L670)
A [*definition domain*](#def:definition_domain "6.3One-definition rule[basic.def.odr]") is
a [*private-module-fragment*](module.private.frag#nt:private-module-fragment "10.5Private module fragment[module.private.frag]") or
the portion of a translation unit
excluding its [*private-module-fragment*](module.private.frag#nt:private-module-fragment "10.5Private module fragment[module.private.frag]") (if any)[.](#13.sentence-1)
A definition of an inline function or variable shall be reachable
from the end of every definition domain
in which it is odr-used outside of a discarded statement[.](#13.sentence-2)
[14](#14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L679)
A definition of a class shall be reachable in every context in which
the class is used in a way that requires the class type to be complete[.](#14.sentence-1)
[*Example [6](#example-6)*:
The following complete translation unit is well-formed,
even though it never defines X:struct X; // declare X as a struct typestruct X* x1; // use X in pointer formation X* x2; // use X in pointer formation
— *end example*]
[*Note [3](#note-3)*:
The rules for declarations and expressions
describe in which contexts complete class types are required[.](#14.sentence-3)
A class
type T must be complete if
- [(14.1)](#14.1)
an object of type T is [defined](basic.def "6.2Declarations and definitions[basic.def]"), or
- [(14.2)](#14.2)
a non-static class [data member](class.mem#def:data_member "11.4Class members[class.mem]") of
type T is declared, or
- [(14.3)](#14.3)
T is used as the allocated type or array element type in a[*new-expression*](expr.new#nt:new-expression "7.6.2.8New[expr.new]") ([[expr.new]](expr.new "7.6.2.8New")), or
- [(14.4)](#14.4)
an lvalue-to-rvalue conversion is applied to
a glvalue referring
to an object of type T ([[conv.lval]](conv.lval "7.3.2Lvalue-to-rvalue conversion")), or
- [(14.5)](#14.5)
an expression is converted (either implicitly or explicitly) to
type T ([[conv]](conv "7.3Standard conversions"), [[expr.type.conv]](expr.type.conv "7.6.1.4Explicit type conversion (functional notation)"), [[expr.dynamic.cast]](expr.dynamic.cast "7.6.1.7Dynamic cast"), [[expr.static.cast]](expr.static.cast "7.6.1.9Static cast"), [[expr.cast]](expr.cast "7.6.3Explicit type conversion (cast notation)")), or
- [(14.6)](#14.6)
an expression that is not a null pointer constant, and has type
other than cv void*, is converted to the type pointer to T or reference to T using a standard conversion ([[conv]](conv "7.3Standard conversions")),
a dynamic_cast ([[expr.dynamic.cast]](expr.dynamic.cast "7.6.1.7Dynamic cast")) or
a static_cast ([[expr.static.cast]](expr.static.cast "7.6.1.9Static cast")), or
- [(14.7)](#14.7)
a class member access operator is applied to an expression of typeT ([[expr.ref]](expr.ref "7.6.1.5Class member access")), or
- [(14.8)](#14.8)
the typeid operator ([[expr.typeid]](expr.typeid "7.6.1.8Type identification")) or thesizeof operator ([[expr.sizeof]](expr.sizeof "7.6.2.5Sizeof")) is applied to an operand of
type T, or
- [(14.9)](#14.9)
a function with a return type or argument type of type T is defined ([[basic.def]](basic.def "6.2Declarations and definitions")) or [called](expr.call "7.6.1.3Function call[expr.call]"), or
- [(14.10)](#14.10)
a class with a base class of type T is
defined ([[class.derived]](class.derived "11.7Derived classes")), or
- [(14.11)](#14.11)
an lvalue of type T is assigned to ([[expr.assign]](expr.assign "7.6.19Assignment and compound assignment operators")), or
- [(14.12)](#14.12)
the type T is the subject of analignof expression ([[expr.alignof]](expr.alignof "7.6.2.6Alignof")), or
- [(14.13)](#14.13)
an [*exception-declaration*](except.pre#nt:exception-declaration "14.1Preamble[except.pre]") has type T, reference toT, or pointer to T ([[except.handle]](except.handle "14.4Handling an exception"))[.](#14.sentence-4)
— *end note*]
[15](#15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L730)
If a definable item D is defined in a translation unit
by an injected declaration X ([[expr.const]](expr.const "7.7Constant expressions")) and
another translation unit contains a definition of D,
that definition shall be an injected declaration
having the same characteristic sequence as X;
a diagnostic is required only if D is attached to a named module and
a prior definition is reachable at the point where a later definition occurs[.](#15.sentence-1)
[16](#16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L739)
For any other definable item D with definitions in multiple translation units,
- [(16.1)](#16.1)
if D is a non-inline non-templated function or variable, or
- [(16.2)](#16.2)
if the definitions in different translation units
do not satisfy the following requirements,
the program is ill-formed;
a diagnostic is required only
if the definable item is attached to a named module and
a prior definition is reachable at the point where a later definition occurs[.](#16.sentence-1)
Given such an item,
for all definitions of D, or,
if D is an unnamed enumeration,
for all definitions of D that are reachable at any given program point,
the following requirements shall be satisfied[.](#16.sentence-2)
- [(16.3)](#16.3)
Each such definition
shall not be attached to a named module ([[module.unit]](module.unit "10.1Module units and purviews"))[.](#16.3.sentence-1)
- [(16.4)](#16.4)
Each such definition shall consist of
the same sequence of tokens,
where the definition of a closure type
is considered to consist of the sequence of tokens of
the corresponding [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1General[expr.prim.lambda.general]")[.](#16.4.sentence-1)
- [(16.5)](#16.5)
In each such definition, corresponding names, looked up
according to [[basic.lookup]](basic.lookup "6.5Name lookup"), shall denote the same entity, after
overload resolution ([[over.match]](over.match "12.2Overload resolution")) and after matching of partial
template specializations ([[temp.spec.partial.match]](temp.spec.partial.match "13.7.6.2Matching of partial specializations")), except that a name can refer to
* [(16.5.1)](#16.5.1)
a non-volatile const object with internal or no linkage if the object
+
[(16.5.1.1)](#16.5.1.1)
has the same literal type in all definitions of D,
+
[(16.5.1.2)](#16.5.1.2)
is initialized with a [constant expression](expr.const "7.7Constant expressions[expr.const]"),
+
[(16.5.1.3)](#16.5.1.3)
is not odr-used in any definition of D, and
+
[(16.5.1.4)](#16.5.1.4)
has the same value in all definitions of D,
or
* [(16.5.2)](#16.5.2)
a reference with internal or no linkage
initialized with a constant expression such that
the reference refers to the same object or function in all definitions of D[.](#16.5.sentence-1)
- [(16.6)](#16.6)
In each such definition, except within
the default arguments and default template arguments of D,
corresponding [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1General[expr.prim.lambda.general]")*s* shall have
the same closure type (see below)[.](#16.6.sentence-1)
- [(16.7)](#16.7)
In each such definition, corresponding entities shall have the
same language linkage[.](#16.7.sentence-1)
- [(16.8)](#16.8)
In each such definition,
const objects with static or thread storage duration
shall be constant-initialized if
the object is constant-initialized in any such definition[.](#16.8.sentence-1)
- [(16.9)](#16.9)
In each such definition,
corresponding manifestly constant-evaluated expressions
that are not value-dependent
shall have the same value ([[expr.const]](expr.const "7.7Constant expressions"), [[temp.dep.constexpr]](temp.dep.constexpr "13.8.3.4Value-dependent expressions"))[.](#16.9.sentence-1)
- [(16.10)](#16.10)
In each such definition, the overloaded operators referred
to, the implicit calls to conversion functions, constructors, operator
new functions and operator delete functions, shall refer to the same
function[.](#16.10.sentence-1)
- [(16.11)](#16.11)
In each such definition,
a default argument used by an (implicit or explicit) function call or
a default template argument used by an (implicit or explicit)[*template-id*](temp.names#nt:template-id "13.3Names of template specializations[temp.names]"),[*simple-template-id*](temp.names#nt:simple-template-id "13.3Names of template specializations[temp.names]"), or[*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6Splice specifiers[basic.splice]") is treated as if its token sequence
were present in the definition of D;
that is, the default argument or default template argument
is subject to the requirements described in this paragraph (recursively)[.](#16.11.sentence-1)
- [(16.12)](#16.12)
In each such definition,
corresponding [*reflect-expression*](expr.reflect#nt:reflect-expression "7.6.2.10The reflection operator[expr.reflect]")*s* ([[expr.reflect]](expr.reflect "7.6.2.10The reflection operator"))
compute equivalent values ([[expr.eq]](expr.eq "7.6.10Equality operators"))[.](#16.12.sentence-1)
[17](#17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L824)
For the purposes of the preceding requirements:
- [(17.1)](#17.1)
If D is a class with an implicitly-declared
constructor ([[class.default.ctor]](class.default.ctor "11.4.5.2Default constructors"), [[class.copy.ctor]](class.copy.ctor "11.4.5.3Copy/move constructors")),
it is as if the constructor was
implicitly defined in every translation unit where it is odr-used, and the
implicit definition in every translation unit shall call the same
constructor for a subobject of D[.](#17.1.sentence-1)
[*Example [7](#example-7)*: // translation unit 1:struct X { X(int, int);
X(int, int, int);};
X::X(int, int = 0) { }class D { X x = 0;};
D d1; // X(int, int) called by D()// translation unit 2:struct X { X(int, int);
X(int, int, int);};
X::X(int, int = 0, int = 0) { }class D { X x = 0;};
D d2; // X(int, int, int) called by D();// D()'s implicit definition violates the ODR — *end example*]
- [(17.2)](#17.2)
If D is a class with
a defaulted three-way comparison operator function ([[class.spaceship]](class.spaceship "11.10.3Three-way comparison")),
it is as if the operator was
implicitly defined in every translation unit where it is odr-used, and the
implicit definition in every translation unit shall call the same
comparison operators for each subobject of D[.](#17.2.sentence-1)
- [(17.3)](#17.3)
If D is a template and is defined in more than one
translation unit, the requirements
apply both to names from the template's enclosing scope used in the
template definition, and also to dependent names at
the point of instantiation ([[temp.dep]](temp.dep "13.8.3Dependent names"))[.](#17.3.sentence-1)
[18](#18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L875)
These requirements also apply to corresponding entities
defined within each definition of D (including the closure types of [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1General[expr.prim.lambda.general]")*s*,
but excluding entities defined within default arguments or
default template arguments of either D or
an entity not defined within D)[.](#18.sentence-1)
For each such entity and for D itself,
the behavior is as if there is a single entity with a single definition,
including in the application of these requirements to other entities[.](#18.sentence-2)
[*Note [4](#note-4)*:
The entity is still declared in multiple translation units, and [[basic.link]](basic.link "6.7Program and linkage") still applies to these declarations[.](#18.sentence-3)
In particular,[*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1General[expr.prim.lambda.general]")*s* ([[expr.prim.lambda]](expr.prim.lambda "7.5.6Lambda expressions"))
appearing in the type of D can result
in the different declarations having distinct types, and[*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1General[expr.prim.lambda.general]")*s* appearing in a default argument of D might still denote different types in different translation units[.](#18.sentence-4)
— *end note*]
[19](#19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L895)
[*Example [8](#example-8)*: inline void f(bool cond, void (*p)()) {if (cond) f(false, []{});}inline void g(bool cond, void (*p)() = []{}) {if (cond) g(false);}struct X {void h(bool cond, void (*p)() = []{}) {if (cond) h(false); }};
If the definition of f appears in multiple translation units,
the behavior of the program is as if
there is only one definition of f[.](#19.sentence-1)
If the definition of g appears in multiple translation units,
the program is ill-formed (no diagnostic required) because
each such definition uses a default argument that
refers to a distinct [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1General[expr.prim.lambda.general]") closure type[.](#19.sentence-2)
The definition of X can appear
in multiple translation units of a valid program;
the [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1General[expr.prim.lambda.general]")*s* defined within
the default argument of X::h within the definition of X denote the same closure type in each translation unit[.](#19.sentence-3)
— *end example*]
[20](#20)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L925)
If, at any point in the program,
there is more than one
reachable unnamed enumeration definition in the same scope
that have the same first enumerator name and
do not have typedef names for linkage purposes ([[dcl.enum]](dcl.enum "9.8.1Enumeration declarations")),
those unnamed enumeration types shall be the same; no diagnostic required[.](#20.sentence-1)
[16)](#footnote-16)[16)](#footnoteref-16)
An implementation is not required
to call allocation and
deallocation functions from constructors or destructors; however, this
is a permissible implementation technique[.](#footnote-16.sentence-1)

1780
cppdraft/basic/exec.md Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,102 @@
[basic.extended.fp]
# 6 Basics [[basic]](./#basic)
## 6.9 Types [[basic.types]](basic.types#basic.extended.fp)
### 6.9.3 Optional extended floating-point types [basic.extended.fp]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5705)
If the implementation supports an extended floating-point type ([[basic.fundamental]](basic.fundamental "6.9.2Fundamental types"))
whose properties are specified by
the ISO/IEC 60559 floating-point interchange format binary16,
then the [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4The typedef specifier[dcl.typedef]") std::float16_t is declared in the header [<stdfloat>](stdfloat.syn#header:%3cstdfloat%3e "17.4.2Header <stdfloat> synopsis[stdfloat.syn]") and names such a type,
the macro __STDCPP_FLOAT16_T__ is defined ([[cpp.predefined]](cpp.predefined "15.12Predefined macro names")), and
the floating-point literal suffixes f16 and F16 are supported ([[lex.fcon]](lex.fcon "5.13.4Floating-point literals"))[.](#1.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5715)
If the implementation supports an extended floating-point type
whose properties are specified by
the ISO/IEC 60559 floating-point interchange format binary32,
then the [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4The typedef specifier[dcl.typedef]") std::float32_t is declared in the header [<stdfloat>](stdfloat.syn#header:%3cstdfloat%3e "17.4.2Header <stdfloat> synopsis[stdfloat.syn]") and names such a type,
the macro __STDCPP_FLOAT32_T__ is defined, and
the floating-point literal suffixes f32 and F32 are supported[.](#2.sentence-1)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5724)
If the implementation supports an extended floating-point type
whose properties are specified by
the ISO/IEC 60559 floating-point interchange format binary64,
then the [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4The typedef specifier[dcl.typedef]") std::float64_t is declared in the header [<stdfloat>](stdfloat.syn#header:%3cstdfloat%3e "17.4.2Header <stdfloat> synopsis[stdfloat.syn]") and names such a type,
the macro __STDCPP_FLOAT64_T__ is defined, and
the floating-point literal suffixes f64 and F64 are supported[.](#3.sentence-1)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5733)
If the implementation supports an extended floating-point type
whose properties are specified by
the ISO/IEC 60559 floating-point interchange format binary128,
then the [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4The typedef specifier[dcl.typedef]") std::float128_t is declared in the header [<stdfloat>](stdfloat.syn#header:%3cstdfloat%3e "17.4.2Header <stdfloat> synopsis[stdfloat.syn]") and names such a type,
the macro __STDCPP_FLOAT128_T__ is defined, and
the floating-point literal suffixes f128 and F128 are supported[.](#4.sentence-1)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5742)
If the implementation supports an extended floating-point type
with the properties, as specified by ISO/IEC 60559, of
radix (b) of 2,
storage width in bits (k) of 16,
precision in bits (p) of 8,
maximum exponent (emax) of 127, and
exponent field width in bits (w) of 8, then
the [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4The typedef specifier[dcl.typedef]") std::bfloat16_t is declared in the header [<stdfloat>](stdfloat.syn#header:%3cstdfloat%3e "17.4.2Header <stdfloat> synopsis[stdfloat.syn]") and names such a type,
the macro __STDCPP_BFLOAT16_T__ is defined, and
the floating-point literal suffixes bf16 and BF16 are supported[.](#5.sentence-1)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5755)
[*Note [1](#note-1)*:
A summary of the parameters for each type is given in Table [15](#tab:basic.extended.fp "Table 15: Properties of named extended floating-point types")[.](#6.sentence-1)
The precision p includes the implicit 1 bit at the beginning of the significand,
so the storage used for the significand is p−1 bits[.](#6.sentence-2)
ISO/IEC 60559 does not assign a name for a type
having the parameters specified for std::bfloat16_t[.](#6.sentence-3)
— *end note*]
Table [15](#tab:basic.extended.fp) — Properties of named extended floating-point types [[tab:basic.extended.fp]](./tab:basic.extended.fp)
| [🔗](#tab:basic.extended.fp-row-1)<br>**Parameter** | **float16_t** | **float32_t** | **float64_t** | **float128_t** | **bfloat16_t** |
| --- | --- | --- | --- | --- | --- |
| [🔗](#tab:basic.extended.fp-row-2)<br>ISO/IEC 60559 name | binary16 | binary32 | binary64 | binary128 | |
| [🔗](#tab:basic.extended.fp-row-3)<br>k, storage width in bits | 16 | 32 | 64 | 128 | 16 |
| [🔗](#tab:basic.extended.fp-row-4)<br>p, precision in bits | 11 | 24 | 53 | 113 | 8 |
| [🔗](#tab:basic.extended.fp-row-5)<br>emax, maximum exponent | 15 | 127 | 1023 | 16383 | 127 |
| [🔗](#tab:basic.extended.fp-row-6)<br>w, exponent field width in bits | 5 | 8 | 11 | 15 | 8 |
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5777)
*Recommended practice*: Any names that the implementation provides for
the extended floating-point types described in this subsection
that are in addition to the names declared in the [<stdfloat>](stdfloat.syn#header:%3cstdfloat%3e "17.4.2Header <stdfloat> synopsis[stdfloat.syn]") header
should be chosen to increase compatibility and interoperability
with the interchange types_Float16, _Float32, _Float64, and _Float128 defined in ISO/IEC TS 18661-3 and with future versions of ISO/IEC 9899[.](#7.sentence-1)

View File

@@ -0,0 +1,524 @@
[basic.fundamental]
# 6 Basics [[basic]](./#basic)
## 6.9 Types [[basic.types]](basic.types#basic.fundamental)
### 6.9.2 Fundamental types [basic.fundamental]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5300)
There are five [*standard signed integer types*](#def:type,standard_signed_integer "6.9.2Fundamental types[basic.fundamental]"):“signed char”, “short int”, “int”,
“long int”, and “long long int”[.](#1.sentence-1)
In
this list, each type provides at least as much storage as those
preceding it in the list[.](#1.sentence-2)
There may also be implementation-defined[*extended signed integer types*](#def:type,extended_signed_integer "6.9.2Fundamental types[basic.fundamental]")[.](#1.sentence-3)
The standard and extended signed integer types are collectively called[*signed integer types*](#def:type,signed_integer "6.9.2Fundamental types[basic.fundamental]")[.](#1.sentence-4)
The range of representable values for a signed integer type is−2N−1 to 2N−ˆ’1 (inclusive),
where N is called the [*width*](simd.general#def:width "29.10.1General[simd.general]") of the type[.](#1.sentence-5)
[*Note [1](#note-1)*:
Plain ints are intended to have
the natural width suggested by the architecture of the execution environment;
the other signed integer types are provided to meet special needs[.](#1.sentence-6)
— *end note*]
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5326)
For each of the standard signed integer types,
there exists a corresponding (but different)[*standard unsigned integer type*](#def:type,standard_unsigned_integer "6.9.2Fundamental types[basic.fundamental]"):“unsigned char”, “unsigned short int”,
“unsigned int”, “unsigned long int”, and
“unsigned long long int”[.](#2.sentence-1)
Likewise, for each of the extended signed integer types,
there exists a corresponding [*extended unsigned integer type*](#def:type,extended_unsigned_integer "6.9.2Fundamental types[basic.fundamental]")[.](#2.sentence-2)
The standard and extended unsigned integer types
are collectively called [*unsigned integer types*](#def:type,unsigned_integer "6.9.2Fundamental types[basic.fundamental]")[.](#2.sentence-3)
An unsigned integer type has the same width *N* as the corresponding signed integer type[.](#2.sentence-4)
The range of representable values for the unsigned type is0 to 2N−1 (inclusive);
arithmetic for the unsigned type is performed modulo 2N[.](#2.sentence-5)
[*Note [2](#note-2)*:
Unsigned arithmetic does not overflow[.](#2.sentence-6)
Overflow for signed arithmetic yields undefined behavior ([[expr.pre]](expr.pre "7.1Preamble"))[.](#2.sentence-7)
— *end note*]
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5354)
An unsigned integer type has the same
object representation,
value representation, and
alignment requirements ([[basic.align]](basic.align "6.8.3Alignment"))
as the corresponding signed integer type[.](#3.sentence-1)
For each value x of a signed integer type,
the value of the corresponding unsigned integer type
congruent to x modulo 2N has the same value
of corresponding bits in its value representation[.](#3.sentence-2)[30](#footnote-30 "This is also known as two's complement representation.")
[*Example [1](#example-1)*:
The value −1 of a signed integer type has the same representation as
the largest value of the corresponding unsigned type[.](#3.sentence-3)
— *end example*]
Table [14](#tab:basic.fundamental.width) — Minimum width [[tab:basic.fundamental.width]](./tab:basic.fundamental.width)
| [🔗](#tab:basic.fundamental.width-row-1)<br>**Type** | **Minimum width N** |
| --- | --- |
| [🔗](#tab:basic.fundamental.width-row-2)<br>signed char | 8 |
| [🔗](#tab:basic.fundamental.width-row-3)<br>short int | 16 |
| [🔗](#tab:basic.fundamental.width-row-4)<br>int | 16 |
| [🔗](#tab:basic.fundamental.width-row-5)<br>long int | 32 |
| [🔗](#tab:basic.fundamental.width-row-6)<br>long long int | 64 |
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5385)
The width of each standard signed integer type
shall not be less than the values specified in Table [14](#tab:basic.fundamental.width "Table 14: Minimum width")[.](#4.sentence-1)
The value representation of a signed or unsigned integer type
comprises N bits, where N is the respective width[.](#4.sentence-2)
Each set of values for any padding bits ([[basic.types.general]](basic.types.general "6.9.1General"))
in the object representation are
alternative representations of the value specified by the value representation[.](#4.sentence-3)
[*Note [3](#note-3)*:
Padding bits have unspecified value, but cannot cause traps[.](#4.sentence-4)
In contrast, see ISO/IEC 9899:2024 6.2.6.2[.](#4.sentence-5)
— *end note*]
[*Note [4](#note-4)*:
The signed and unsigned integer types satisfy
the constraints given in ISO/IEC 9899:2024 5.2.4.2.1[.](#4.sentence-6)
— *end note*]
Except as specified above,
the width of a signed or unsigned integer type isimplementation-defined[.](#4.sentence-7)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5405)
Each value x of an unsigned integer type with width N has
a unique representation x=x020+x121+…+xN−12N−1,
where each coefficient xi is either 0 or 1;
this is called the [*base-2 representation*](#def:base-2_representation "6.9.2Fundamental types[basic.fundamental]") of x[.](#5.sentence-1)
The base-2 representation of a value of signed integer type is
the base-2 representation of the congruent value
of the corresponding unsigned integer type[.](#5.sentence-2)
The standard signed integer types and standard unsigned integer types
are collectively called the [*standard integer types*](#def:type,standard_integer "6.9.2Fundamental types[basic.fundamental]"), and the extended
signed integer types and extended
unsigned integer types are collectively called the[*extended integer types*](#def:type,extended_integer "6.9.2Fundamental types[basic.fundamental]")[.](#5.sentence-3)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5419)
A fundamental type specified to have
a signed or unsigned integer type as its [*underlying type*](#def:type,underlying "6.9.2Fundamental types[basic.fundamental]") has
the same object representation,
value representation,
alignment requirements ([[basic.align]](basic.align "6.8.3Alignment")), and
range of representable values as the underlying type[.](#6.sentence-1)
Further, each value has the same representation in both types[.](#6.sentence-2)
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5428)
Type char is a distinct type
that has an implementation-defined choice of
“signed char” or “unsigned char” as its underlying type[.](#7.sentence-1)
The three types char, signed char, and unsigned char are collectively called[*ordinary character types*](#def:type,ordinary_character "6.9.2Fundamental types[basic.fundamental]")[.](#7.sentence-2)
The ordinary character types and char8_t are collectively called [*narrow character types*](#def:type,narrow_character "6.9.2Fundamental types[basic.fundamental]")[.](#7.sentence-3)
For narrow character types,
each possible bit pattern of the object representation represents
a distinct value[.](#7.sentence-4)
[*Note [5](#note-5)*:
This requirement does not hold for other types[.](#7.sentence-5)
— *end note*]
[*Note [6](#note-6)*:
A bit-field of narrow character type whose width is larger than
the width of that type has padding bits; see [[basic.types.general]](basic.types.general "6.9.1General")[.](#7.sentence-6)
— *end note*]
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5454)
Type wchar_t is a distinct type that has
an implementation-defined
signed or unsigned integer type as its underlying type[.](#8.sentence-1)
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5462)
Type char8_t denotes a distinct type
whose underlying type is unsigned char[.](#9.sentence-1)
Types char16_t and char32_t denote distinct types
whose underlying types are uint_least16_t and uint_least32_t,
respectively, in [<cstdint>](cstdint.syn#header:%3ccstdint%3e "17.4.1Header <cstdint> synopsis[cstdint.syn]")[.](#9.sentence-2)
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5478)
Type bool is a distinct type that has
the same object representation,
value representation, and
alignment requirements as
an implementation-defined unsigned integer type[.](#10.sentence-1)
The values of type bool aretrue and false[.](#10.sentence-2)
[*Note [7](#note-7)*:
There are no signed, unsigned,short, or long bool types or values[.](#10.sentence-3)
— *end note*]
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5493)
The types char, wchar_t,char8_t, char16_t, and char32_t are collectively called [*character types*](#def:type,character "6.9.2Fundamental types[basic.fundamental]")[.](#11.sentence-1)
The character types, bool,
the signed and unsigned integer types,
and cv-qualified versions ([[basic.type.qualifier]](basic.type.qualifier "6.9.5CV-qualifiers")) thereof,
are collectively termed[*integral types*](#def:integral_type "6.9.2Fundamental types[basic.fundamental]")[.](#11.sentence-2)
A synonym for integral type is [*integer type*](#def:integer_type "6.9.2Fundamental types[basic.fundamental]")[.](#11.sentence-3)
[*Note [8](#note-8)*:
Enumerations ([[dcl.enum]](dcl.enum "9.8.1Enumeration declarations")) are not integral;
however, unscoped enumerations can be promoted to integral types
as specified in [[conv.prom]](conv.prom "7.3.7Integral promotions")[.](#11.sentence-4)
— *end note*]
[12](#12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5510)
The three distinct typesfloat,double,
andlong double can represent floating-point numbers[.](#12.sentence-1)
The type double provides at least as much
precision as float, and the type long double provides at
least as much precision as double[.](#12.sentence-2)
The set of values of the typefloat is a subset of the set of values of the typedouble; the set of values of the type double is a subset
of the set of values of the type long double[.](#12.sentence-3)
The typesfloat, double, and long double,
and cv-qualified versions ([[basic.type.qualifier]](basic.type.qualifier "6.9.5CV-qualifiers")) thereof,
are collectively termed[*standard floating-point types*](#def:type,floating-point,standard "6.9.2Fundamental types[basic.fundamental]")[.](#12.sentence-4)
An implementation may also provide additional types
that represent floating-point values and define them (and cv-qualified versions thereof) to be[*extended floating-point types*](#def:type,floating-point,extended "6.9.2Fundamental types[basic.fundamental]")[.](#12.sentence-5)
The standard and extended floating-point types
are collectively termed [*floating-point types*](#def:type,floating-point "6.9.2Fundamental types[basic.fundamental]")[.](#12.sentence-6)
[*Note [9](#note-9)*:
Any additional implementation-specific types representing floating-point values
that are not defined by the implementation to be extended floating-point types
are not considered to be floating-point types, and
this document imposes no requirements on them or
their interactions with floating-point types[.](#12.sentence-7)
— *end note*]
Except as specified in [[basic.extended.fp]](basic.extended.fp "6.9.3Optional extended floating-point types"),
the object and value representations and accuracy of operations
of floating-point types are implementation-defined[.](#12.sentence-8)
[13](#13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5548)
The minimum range of representable values for a floating-point type is
the most negative finite floating-point number representable
in that type through
the most positive finite floating-point number representable in that type[.](#13.sentence-1)
In addition, if negative infinity is representable in a type,
the range of that type is extended to all negative real numbers;
likewise, if positive infinity is representable in a type,
the range of that type is extended to all positive real numbers[.](#13.sentence-2)
[*Note [10](#note-10)*:
Since negative and positive infinity are representable
in ISO/IEC 60559 formats,
all real numbers lie within the range of representable values of
a floating-point type adhering to ISO/IEC 60559[.](#13.sentence-3)
— *end note*]
[14](#14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5564)
Integral and floating-point types are collectively
termed [*arithmetic types*](#def:type,arithmetic "6.9.2Fundamental types[basic.fundamental]")[.](#14.sentence-1)
[*Note [11](#note-11)*:
Properties of the arithmetic types,
such as their minimum and maximum representable value,
can be queried using the facilities in the standard library headers[<limits>](limits.syn#header:%3climits%3e "17.3.3Header <limits> synopsis[limits.syn]"),[<climits>](climits.syn#header:%3cclimits%3e "17.3.6Header <climits> synopsis[climits.syn]"), and[<cfloat>](cfloat.syn#header:%3ccfloat%3e "17.3.7Header <cfloat> synopsis[cfloat.syn]")[.](#14.sentence-2)
— *end note*]
[15](#15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5576)
A type cv void is an incomplete type that cannot be completed; such a type has
an empty set of values[.](#15.sentence-1)
It is used as the return
type for functions that do not return a value[.](#15.sentence-2)
An expression of type cv void shall
be used only as
- [(15.1)](#15.1)
an expression statement ([[stmt.expr]](stmt.expr "8.3Expression statement")),
- [(15.2)](#15.2)
the expression in a return statement ([[stmt.return]](stmt.return "8.8.4The return statement"))
for a function with the return type cv void,
- [(15.3)](#15.3)
an operand of a comma expression ([[expr.comma]](expr.comma "7.6.20Comma operator")),
- [(15.4)](#15.4)
the second or third operand of ?: ([[expr.cond]](expr.cond "7.6.16Conditional operator")),
- [(15.5)](#15.5)
the operand of a typeid expression ([[expr.typeid]](expr.typeid "7.6.1.8Type identification")),
- [(15.6)](#15.6)
the operand of a noexcept operator ([[expr.unary.noexcept]](expr.unary.noexcept "7.6.2.7noexcept operator")),
- [(15.7)](#15.7)
the operand of a decltype specifier ([[dcl.type.decltype]](dcl.type.decltype "9.2.9.6Decltype specifiers")), or
- [(15.8)](#15.8)
the operand of an explicit conversion to typecv void ([[expr.type.conv]](expr.type.conv "7.6.1.4Explicit type conversion (functional notation)"), [[expr.static.cast]](expr.static.cast "7.6.1.9Static cast"), [[expr.cast]](expr.cast "7.6.3Explicit type conversion (cast notation)"))[.](#15.sentence-3)
[16](#16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5597)
The types denoted by cv std::nullptr_t are distinct types[.](#16.sentence-1)
A prvalue of type std::nullptr_t is a null pointer
constant ([[conv.ptr]](conv.ptr "7.3.12Pointer conversions"))[.](#16.sentence-2)
Such values participate in the pointer and the
pointer-to-member conversions ([[conv.ptr]](conv.ptr "7.3.12Pointer conversions"), [[conv.mem]](conv.mem "7.3.13Pointer-to-member conversions"))[.](#16.sentence-3)
sizeof(std::nullptr_t) shall be equal to sizeof(void*)[.](#16.sentence-4)
[17](#17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5604)
A value of type std::meta::info is called a [*reflection*](#def:reflection "6.9.2Fundamental types[basic.fundamental]")[.](#17.sentence-1)
There exists a unique [*null reflection*](#def:reflection,null "6.9.2Fundamental types[basic.fundamental]");
every other reflection is a representation of
- [(17.1)](#17.1)
a value of scalar type ([[temp.param]](temp.param "13.2Template parameters")),
- [(17.2)](#17.2)
an object with static storage duration ([[basic.stc]](basic.stc "6.8.6Storage duration")),
- [(17.3)](#17.3)
a variable ([[basic.pre]](basic.pre "6.1Preamble")),
- [(17.4)](#17.4)
a structured binding ([[dcl.struct.bind]](dcl.struct.bind "9.7Structured binding declarations")),
- [(17.5)](#17.5)
a function ([[dcl.fct]](dcl.fct "9.3.4.6Functions")),
- [(17.6)](#17.6)
a function parameter,
- [(17.7)](#17.7)
an enumerator ([[dcl.enum]](dcl.enum "9.8.1Enumeration declarations")),
- [(17.8)](#17.8)
an annotation ([[dcl.attr.grammar]](dcl.attr.grammar "9.13.1Attribute syntax and semantics")),
- [(17.9)](#17.9)
a type alias ([[dcl.typedef]](dcl.typedef "9.2.4The typedef specifier")),
- [(17.10)](#17.10)
a type ([[basic.types]](basic.types "6.9Types")),
- [(17.11)](#17.11)
a class member ([[class.mem]](class.mem "11.4Class members")),
- [(17.12)](#17.12)
an unnamed bit-field ([[class.bit]](class.bit "11.4.10Bit-fields")),
- [(17.13)](#17.13)
a class template ([[temp.pre]](temp.pre "13.1Preamble")),
- [(17.14)](#17.14)
a function template,
- [(17.15)](#17.15)
a variable template,
- [(17.16)](#17.16)
an alias template ([[temp.alias]](temp.alias "13.7.8Alias templates")),
- [(17.17)](#17.17)
a concept ([[temp.concept]](temp.concept "13.7.9Concept definitions")),
- [(17.18)](#17.18)
a namespace alias ([[namespace.alias]](namespace.alias "9.9.3Namespace alias")),
- [(17.19)](#17.19)
a namespace ([[basic.namespace.general]](basic.namespace.general "9.9.1General")),
- [(17.20)](#17.20)
a direct base class relationship ([[class.derived.general]](class.derived.general "11.7.1General")), or
- [(17.21)](#17.21)
a data member description ([[class.mem.general]](class.mem.general "11.4.1General"))[.](#17.sentence-2)
A reflection is said to [*represent*](#def:represent "6.9.2Fundamental types[basic.fundamental]") the corresponding construct[.](#17.sentence-3)
[*Note [12](#note-12)*:
A reflection of a value can be produced by library functions such asstd::meta::constant_of and std::meta::reflect_constant[.](#17.sentence-4)
— *end note*]
[*Example [2](#example-2)*: int arr[] = {1, 2, 3};auto [a1, a2, a3] = arr;void fn();enum Enum { A };using Alias = int;struct B {};struct S : B {int mem; int : 0;};template<auto> struct TCls {};template<auto> void TFn();template<auto> int TVar;template<auto> concept Concept = requires { true; };namespace NS {};namespace NSAlias = NS;
constexpr auto ctx = std::meta::access_context::current();
constexpr auto r1 = std::meta::reflect_constant(42); // represents int value of 42constexpr auto r2 = std::meta::reflect_object(arr[1]); // represents int objectconstexpr auto r3 = ^^arr; // represents a variableconstexpr auto r4 = ^^a3; // represents a structured bindingconstexpr auto r5 = ^^fn; // represents a functionconstexpr auto r6 = ^^Enum::A; // represents an enumeratorconstexpr auto r7 = ^^Alias; // represents a type aliasconstexpr auto r8 = ^^S; // represents a typeconstexpr auto r9 = ^^S::mem; // represents a class memberconstexpr auto r10 = std::meta::members_of(^^S, ctx)[1]; // represents an unnamed bit-fieldconstexpr auto r11 = ^^TCls; // represents a class templateconstexpr auto r12 = ^^TFn; // represents a function templateconstexpr auto r13 = ^^TVar; // represents a variable templateconstexpr auto r14 = ^^Concept; // represents a conceptconstexpr auto r15 = ^^NSAlias; // represents a namespace aliasconstexpr auto r16 = ^^NS; // represents a namespaceconstexpr auto r17 = std::meta::bases_of(^^S, ctx)[0]; // represents a direct base class relationshipconstexpr auto r18 = std::meta::data_member_spec(^^int, {.name="member"}); // represents a data member description — *end example*]
[18](#18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5679)
*Recommended practice*: Implementations should not represent other constructs
specified in this document, such as[*using-declarator*](namespace.udecl#nt:using-declarator "9.10The using declaration[namespace.udecl]")*s*,
partial template specializations,
attributes, placeholder types,
statements, or
expressions,
as values of type std::meta::info[.](#18.sentence-1)
[*Note [13](#note-13)*:
Future revisions of this document can specify semantics for reflections
representing any such constructs[.](#18.sentence-2)
— *end note*]
[19](#19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5694)
The types described in this subclause
are called [*fundamental types*](#def:fundamental_type "6.9.2Fundamental types[basic.fundamental]")[.](#19.sentence-1)
[*Note [14](#note-14)*:
Even if the implementation defines two or more fundamental types to have the
same value representation, they are nevertheless different types[.](#19.sentence-2)
— *end note*]
[30)](#footnote-30)[30)](#footnoteref-30)
This
is also known as two's complement representation[.](#footnote-30.sentence-1)

121
cppdraft/basic/indet.md Normal file
View File

@@ -0,0 +1,121 @@
[basic.indet]
# 6 Basics [[basic]](./#basic)
## 6.8 Memory and objects [[basic.memobj]](basic.memobj#basic.indet)
### 6.8.5 Indeterminate and erroneous values [basic.indet]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4119)
When storage for an object with automatic or dynamic storage duration
is obtained,
the bytes comprising the storage for the object
have the following initial value:
- [(1.1)](#1.1)
If the object has dynamic storage duration, or
is the object associated with a variable or function parameter
whose first declaration is marked with
the [[indeterminate]] attribute ([[dcl.attr.indet]](dcl.attr.indet "9.13.6Indeterminate storage")),
the bytes have [*indeterminate values*](#def:value,indeterminate "6.8.5Indeterminate and erroneous values[basic.indet]");
- [(1.2)](#1.2)
otherwise, the bytes have [*erroneous values*](#def:value,erroneous "6.8.5Indeterminate and erroneous values[basic.indet]"),
where each value is determined by the implementation
independently of the state of the program[.](#1.sentence-1)
If no initialization is performed for an object (including subobjects),
such a byte retains its initial value
until that value is replaced ([[dcl.init.general]](dcl.init.general "9.5.1General"), [[expr.assign]](expr.assign "7.6.19Assignment and compound assignment operators"))[.](#1.sentence-2)
If any bit in the value representation has an indeterminate value,
the object has an indeterminate value;
otherwise, if any bit in the value representation has an erroneous value,
the object has an erroneous value ([[conv.lval]](conv.lval "7.3.2Lvalue-to-rvalue conversion"))[.](#1.sentence-3)
[*Note [1](#note-1)*:
Objects with static or thread storage duration are zero-initialized,
see [[basic.start.static]](basic.start.static "6.10.3.2Static initialization")[.](#1.sentence-4)
— *end note*]
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4148)
Except in the following cases,
if an indeterminate value is produced by an evaluation,
the behavior is undefined, and
if an erroneous value is produced by an evaluation,
the behavior is erroneous and
the result of the evaluation is the value so produced but is not erroneous:
- [(2.1)](#2.1)
If an indeterminate or erroneous value of
unsigned ordinary character type ([[basic.fundamental]](basic.fundamental "6.9.2Fundamental types"))
or std::byte type ([[cstddef.syn]](cstddef.syn "17.2.1Header <cstddef> synopsis"))
is produced by the evaluation of:
* [(2.1.1)](#2.1.1)
the second or third operand of a [conditional expression](expr.cond "7.6.16Conditional operator[expr.cond]"),
* [(2.1.2)](#2.1.2)
the right operand of a [comma expression](expr.comma "7.6.20Comma operator[expr.comma]"),
* [(2.1.3)](#2.1.3)
the operand of a cast or conversion ([[conv.integral]](conv.integral "7.3.9Integral conversions"), [[expr.type.conv]](expr.type.conv "7.6.1.4Explicit type conversion (functional notation)"), [[expr.static.cast]](expr.static.cast "7.6.1.9Static cast"), [[expr.cast]](expr.cast "7.6.3Explicit type conversion (cast notation)"))
to an unsigned ordinary character type
or std::byte type ([[cstddef.syn]](cstddef.syn "17.2.1Header <cstddef> synopsis")), or
* [(2.1.4)](#2.1.4)
a [discarded-value expression](expr.context#def:discarded-value_expression "7.2.3Context dependence[expr.context]"),
then the result of the operation is an indeterminate value or
that erroneous value, respectively[.](#2.1.sentence-1)
- [(2.2)](#2.2)
If an indeterminate or erroneous value of
unsigned ordinary character type or std::byte type
is produced by the evaluation of
the right operand of a simple assignment operator ([[expr.assign]](expr.assign "7.6.19Assignment and compound assignment operators"))
whose first operand is an lvalue of
unsigned ordinary character type or std::byte type,
an indeterminate value or that erroneous value, respectively, replaces
the value of the object referred to by the left operand[.](#2.2.sentence-1)
- [(2.3)](#2.3)
If an indeterminate or erroneous value of unsigned ordinary character type
is produced by the evaluation of the initialization expression
when initializing an object of unsigned ordinary character type,
that object is initialized to an indeterminate
value or that erroneous value, respectively[.](#2.3.sentence-1)
- [(2.4)](#2.4)
If an indeterminate value of
unsigned ordinary character type or std::byte type
is produced by the evaluation of the initialization expression
when initializing an object of std::byte type,
that object is initialized to an indeterminate value or
that erroneous value, respectively[.](#2.4.sentence-1)
Converting an indeterminate or erroneous value of
unsigned ordinary character type or std::byte type
produces an indeterminate or erroneous value, respectively[.](#2.sentence-2)
In the latter case,
the result of the conversion is the value of the converted operand[.](#2.sentence-3)
[*Example [1](#example-1)*: int f(bool b) {unsigned char *c = new unsigned char; unsigned char d = *c; // OK, d has an indeterminate valueint e = d; // undefined behaviorreturn b ? d : 0; // undefined behavior if b is true}int g(bool b) {unsigned char c; unsigned char d = c; // no erroneous behavior, but d has an erroneous value assert(c == d); // holds, both integral promotions have erroneous behaviorint e = d; // erroneous behaviorreturn b ? d : 0; // erroneous behavior if b is true}void h() {int d1, d2; int e1 = d1; // erroneous behaviorint e2 = d1; // erroneous behavior assert(e1 == e2); // holds assert(e1 == d1); // holds, erroneous behavior assert(e2 == d1); // holds, erroneous behavior std::memcpy(&d2, &d1, sizeof(int)); // no erroneous behavior, but d2 has an erroneous value assert(e1 == d2); // holds, erroneous behavior assert(e2 == d2); // holds, erroneous behavior} — *end example*]

View File

@@ -0,0 +1,73 @@
[basic.ios.cons]
# 31 Input/output library [[input.output]](./#input.output)
## 31.5 Iostreams base classes [[iostreams.base]](iostreams.base#basic.ios.cons)
### 31.5.4 Class template basic_ios [[ios]](ios#basic.ios.cons)
#### 31.5.4.2 Constructors [basic.ios.cons]
[🔗](#lib:basic_ios,constructor)
`explicit basic_ios(basic_streambuf<charT, traits>* sb);
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L1879)
*Effects*: Assigns initial values to its member objects by callinginit(sb)[.](#1.sentence-1)
[🔗](#lib:basic_ios,constructor_)
`basic_ios();
`
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L1891)
*Effects*: Leaves its member objects uninitialized[.](#2.sentence-1)
The object
shall be initialized by callingbasic_ios::init before its first use or before it is destroyed, whichever comes first; otherwise the
behavior is undefined[.](#2.sentence-2)
[🔗](#lib:basic_ios,destructor)
`~basic_ios();
`
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L1906)
*Remarks*: The destructor does not destroyrdbuf()[.](#3.sentence-1)
[🔗](#lib:init,basic_ios)
`void init(basic_streambuf<charT, traits>* sb);
`
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L1918)
*Postconditions*: The postconditions of this function are indicated in Table [142](#tab:basic.ios.cons "Table 142: basic_­ios::init() effects")[.](#4.sentence-1)
Table [142](#tab:basic.ios.cons) — basic_ios::init() effects [[tab:basic.ios.cons]](./tab:basic.ios.cons)
| [🔗](#tab:basic.ios.cons-row-1)<br>**Element** | **Value** |
| --- | --- |
| [🔗](#tab:basic.ios.cons-row-2)<br>rdbuf() | sb |
| [🔗](#tab:basic.ios.cons-row-3)<br>tie() | 0 |
| [🔗](#tab:basic.ios.cons-row-4)<br>rdstate() | goodbit if sb is not a null pointer, otherwise badbit[.](#tab:basic.ios.cons-row-4-column-2-sentence-1) |
| [🔗](#tab:basic.ios.cons-row-5)<br>exceptions() | goodbit |
| [🔗](#tab:basic.ios.cons-row-6)<br>flags() | skipws | dec |
| [🔗](#tab:basic.ios.cons-row-7)<br>width() | 0 |
| [🔗](#tab:basic.ios.cons-row-8)<br>precision() | 6 |
| [🔗](#tab:basic.ios.cons-row-9)<br>fill() | widen(' ') |
| [🔗](#tab:basic.ios.cons-row-10)<br>getloc() | a copy of the value returned by locale() |
| [🔗](#tab:basic.ios.cons-row-11)<br>*iarray* | a null pointer |
| [🔗](#tab:basic.ios.cons-row-12)<br>*parray* | a null pointer |

View File

@@ -0,0 +1,291 @@
[basic.ios.members]
# 31 Input/output library [[input.output]](./#input.output)
## 31.5 Iostreams base classes [[iostreams.base]](iostreams.base#basic.ios.members)
### 31.5.4 Class template basic_ios [[ios]](ios#basic.ios.members)
#### 31.5.4.3 Member functions [basic.ios.members]
[🔗](#lib:tie,basic_ios)
`basic_ostream<charT, traits>* tie() const;
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L1956)
*Returns*: An output sequence that is*tied* to (synchronized with) the sequence controlled by the stream buffer[.](#1.sentence-1)
[🔗](#lib:tie,basic_ios_)
`basic_ostream<charT, traits>* tie(basic_ostream<charT, traits>* tiestr);
`
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L1969)
*Preconditions*: If tiestr is not null, tiestr is not reachable by
traversing the linked list of tied stream objects starting fromtiestr->tie()[.](#2.sentence-1)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L1975)
*Postconditions*: tiestr == tie()[.](#3.sentence-1)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L1979)
*Returns*: The previous value oftie()[.](#4.sentence-1)
[🔗](#lib:rdbuf,basic_ios)
`basic_streambuf<charT, traits>* rdbuf() const;
`
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L1991)
*Returns*: A pointer to thestreambuf associated with the stream[.](#5.sentence-1)
[🔗](#lib:rdbuf,basic_ios_)
`basic_streambuf<charT, traits>* rdbuf(basic_streambuf<charT, traits>* sb);
`
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L2004)
*Effects*: Callsclear()[.](#6.sentence-1)
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L2009)
*Postconditions*: sb == rdbuf()[.](#7.sentence-1)
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L2013)
*Returns*: The previous value ofrdbuf()[.](#8.sentence-1)
[🔗](#lib:imbue,basic_ios)
`locale imbue(const locale& loc);
`
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L2025)
*Effects*: Calls[ios_base::imbue](ios.base.locales#lib:ios_base,imbue "31.5.2.4Functions[ios.base.locales]")(loc) and
ifrdbuf() != 0 thenrdbuf()->[pubimbue](streambuf.locales#lib:basic_streambuf,pubimbue "31.6.3.3.1Locales[streambuf.locales]")(loc)[.](#9.sentence-1)
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L2035)
*Returns*: The prior value ofios_base::imbue()[.](#10.sentence-1)
[🔗](#lib:narrow,basic_ios)
`char narrow(char_type c, char dfault) const;
`
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L2047)
*Returns*: use_facet<ctype<char_type>>(getloc()).narrow(c, dfault)[.](#11.sentence-1)
[🔗](#lib:widen,basic_ios)
`char_type widen(char c) const;
`
[12](#12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L2058)
*Returns*: use_facet<ctype<char_type>>(getloc()).widen(c)[.](#12.sentence-1)
[🔗](#lib:fill,basic_ios)
`char_type fill() const;
`
[13](#13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L2069)
*Returns*: The character used to pad (fill) an output conversion to the specified
field width[.](#13.sentence-1)
[🔗](#lib:fill,basic_ios_)
`char_type fill(char_type fillch);
`
[14](#14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L2081)
*Postconditions*: traits::eq(fillch, fill())[.](#14.sentence-1)
[15](#15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L2085)
*Returns*: The previous value offill()[.](#15.sentence-1)
[🔗](#lib:copyfmt,basic_ios)
`basic_ios& copyfmt(const basic_ios& rhs);
`
[16](#16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L2097)
*Effects*: If(this == addressof(rhs)) is true does nothing[.](#16.sentence-1)
Otherwise assigns to the member objects of*this the corresponding member objects of rhs as follows:
- [(16.1)](#16.1)
calls each registered callback pair (fn, idx) as(*fn)(erase_event, *this, idx);
- [(16.2)](#16.2)
then, assigns to the member objects of *this the corresponding member objects ofrhs, except that
* [(16.2.1)](#16.2.1)
rdstate(), rdbuf(), and exceptions() are left unchanged;
* [(16.2.2)](#16.2.2)
the contents of arrays pointed at by pword and iword are copied,
not the pointers themselves;[263](#footnote-263 "This suggests an infinite amount of copying, but the implementation can keep track of the maximum element of the arrays that is nonzero.") and
* [(16.2.3)](#16.2.3)
if any newly stored pointer values in *this point at objects stored outside
the object rhs and those objects are destroyed when rhs is destroyed, the
newly stored pointer values are altered to point at newly constructed copies of the
objects;
- [(16.3)](#16.3)
then, calls each callback pair that was copied from rhs as(*fn)(copyfmt_event, *this, idx);
- [(16.4)](#16.4)
then, calls exceptions(rhs.exceptions())[.](#16.sentence-2)
[17](#17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L2134)
[*Note [1](#note-1)*:
The second pass through the callback pairs permits a copied pword value to be zeroed, or to have its referent deep copied or reference counted, or to have
other special action taken[.](#17.sentence-1)
— *end note*]
[18](#18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L2141)
*Postconditions*: The postconditions of this function are indicated in Table [143](#tab:basic.ios.copyfmt "Table 143: basic_­ios::copyfmt() effects")[.](#18.sentence-1)
Table [143](#tab:basic.ios.copyfmt) — basic_ios::copyfmt() effects [[tab:basic.ios.copyfmt]](./tab:basic.ios.copyfmt)
| [🔗](#tab:basic.ios.copyfmt-row-1)<br>**Element** | **Value** |
| --- | --- |
| [🔗](#tab:basic.ios.copyfmt-row-2)<br>rdbuf() | *unchanged* |
| [🔗](#tab:basic.ios.copyfmt-row-3)<br>tie() | rhs.tie() |
| [🔗](#tab:basic.ios.copyfmt-row-4)<br>rdstate() | *unchanged* |
| [🔗](#tab:basic.ios.copyfmt-row-5)<br>exceptions() | rhs.exceptions() |
| [🔗](#tab:basic.ios.copyfmt-row-6)<br>flags() | rhs.flags() |
| [🔗](#tab:basic.ios.copyfmt-row-7)<br>width() | rhs.width() |
| [🔗](#tab:basic.ios.copyfmt-row-8)<br>precision() | rhs.precision() |
| [🔗](#tab:basic.ios.copyfmt-row-9)<br>fill() | rhs.fill() |
| [🔗](#tab:basic.ios.copyfmt-row-10)<br>getloc() | rhs.getloc() |
[19](#19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L2167)
*Returns*: *this[.](#19.sentence-1)
[🔗](#lib:move,basic_ios)
`void move(basic_ios& rhs);
void move(basic_ios&& rhs);
`
[20](#20)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L2179)
*Postconditions*: *this has the state thatrhs had before the function call, except thatrdbuf() returns nullptr[.](#20.sentence-1)
rhs is in a valid but
unspecified state, except that rhs.rdbuf() returns the
same value as it returned before the function call, andrhs.tie() returns nullptr[.](#20.sentence-2)
[🔗](#lib:swap,basic_ios)
`void swap(basic_ios& rhs) noexcept;
`
[21](#21)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L2195)
*Effects*: The states of *this and rhs are exchanged, except that rdbuf() returns the same
value as it returned before the function call, and rhs.rdbuf() returns the same value as it returned before the function call[.](#21.sentence-1)
[🔗](#lib:set_rdbuf,basic_ios)
`void set_rdbuf(basic_streambuf<charT, traits>* sb);
`
[22](#22)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L2209)
*Preconditions*: sb != nullptr is true[.](#22.sentence-1)
[23](#23)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L2213)
*Effects*: Associates the basic_streambuf object
pointed to by sb with this stream without callingclear()[.](#23.sentence-1)
[24](#24)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L2219)
*Postconditions*: rdbuf() == sb is true[.](#24.sentence-1)
[25](#25)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L2223)
*Throws*: Nothing[.](#25.sentence-1)
[263)](#footnote-263)[263)](#footnoteref-263)
This suggests an infinite amount of copying, but the implementation can keep
track of the maximum element of the arrays that is nonzero[.](#footnote-263.sentence-1)

334
cppdraft/basic/life.md Normal file
View File

@@ -0,0 +1,334 @@
[basic.life]
# 6 Basics [[basic]](./#basic)
## 6.8 Memory and objects [[basic.memobj]](basic.memobj#basic.life)
### 6.8.4 Lifetime [basic.life]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3821)
In this subclause, “before” and “after” refer to the “happens before”
relation ([[intro.multithread]](intro.multithread "6.10.2Multi-threaded executions and data races"))[.](#1.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3825)
The [*lifetime*](#def:lifetime "6.8.4Lifetime[basic.life]") of an object or reference is a runtime property of the
object or reference[.](#2.sentence-1)
A variable is said to have [*vacuous initialization*](#def:initialization,vacuous "6.8.4Lifetime[basic.life]") if it is default-initialized, no other initialization is performed, and,
if it is of class type or a (possibly multidimensional) array thereof,
a trivial constructor of that class type is selected for
the default-initialization[.](#2.sentence-2)
The lifetime of an object of type T begins when:
- [(2.1)](#2.1)
storage with the proper alignment and size
for type T is obtained, and
- [(2.2)](#2.2)
its initialization (if any) is complete
(including vacuous initialization) ([[dcl.init]](dcl.init "9.5Initializers")),
except that if the object is a union member or subobject thereof,
its lifetime only begins if that union member is the
initialized member in the union ([[dcl.init.aggr]](dcl.init.aggr "9.5.2Aggregates"), [[class.base.init]](class.base.init "11.9.3Initializing bases and members")),
or as described in[[class.union]](class.union "11.5Unions"), [[class.copy.ctor]](class.copy.ctor "11.4.5.3Copy/move constructors"), and [[class.copy.assign]](class.copy.assign "11.4.6Copy/move assignment operator"),
and except as described in [[allocator.members]](allocator.members "20.2.10.2Members")[.](#2.sentence-3)
The lifetime of an object *o* of type T ends when:
- [(2.3)](#2.3)
if T is a non-class type, the object is destroyed, or
- [(2.4)](#2.4)
if T is a class type, the destructor call starts, or
- [(2.5)](#2.5)
the storage which the object occupies is released,
or is reused by an object that is not nested within *o* ([[intro.object]](intro.object "6.8.2Object model"))[.](#2.sentence-4)
When evaluating a [*new-expression*](expr.new#nt:new-expression "7.6.2.8New[expr.new]"),
storage is considered reused after it is returned from the allocation function,
but before the evaluation of the [*new-initializer*](expr.new#nt:new-initializer "7.6.2.8New[expr.new]") ([[expr.new]](expr.new "7.6.2.8New"))[.](#2.sentence-5)
[*Example [1](#example-1)*: struct S {int m;};
void f() { S x{1}; new(&x) S(x.m); // undefined behavior} — *end example*]
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3870)
The lifetime of a reference begins when its initialization is complete[.](#3.sentence-1)
The lifetime of a reference ends as if it were a scalar object requiring storage[.](#3.sentence-2)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3875)
[*Note [1](#note-1)*:
[[class.base.init]](class.base.init "11.9.3Initializing bases and members") describes the lifetime of base and member subobjects[.](#4.sentence-1)
— *end note*]
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3881)
The properties ascribed to objects and references throughout this document
apply for a given object or reference only during its lifetime[.](#5.sentence-1)
[*Note [2](#note-2)*:
In particular, before the lifetime of an object starts and after its
lifetime ends there are significant restrictions on the use of the
object, as described below, in [[class.base.init]](class.base.init "11.9.3Initializing bases and members"), and
in [[class.cdtor]](class.cdtor "11.9.5Construction and destruction")[.](#5.sentence-2)
Also, the behavior of an object under construction
and destruction can differ from the behavior of an object whose
lifetime has started and not ended[.](#5.sentence-3)
[[class.base.init]](class.base.init "11.9.3Initializing bases and members") and [[class.cdtor]](class.cdtor "11.9.5Construction and destruction") describe the behavior of an object during its periods
of construction and destruction[.](#5.sentence-4)
— *end note*]
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3895)
A program may end the lifetime of an object of class type without invoking the
destructor, by reusing or releasing the storage as described above[.](#6.sentence-1)
[*Note [3](#note-3)*:
A [*delete-expression*](expr.delete#nt:delete-expression "7.6.2.9Delete[expr.delete]") ([[expr.delete]](expr.delete "7.6.2.9Delete")) invokes the destructor
prior to releasing the storage[.](#6.sentence-2)
— *end note*]
In this case, the destructor is not implicitly invoked[.](#6.sentence-3)
[*Note [4](#note-4)*:
The correct behavior of a program often depends on
the destructor being invoked for each object of class type[.](#6.sentence-4)
— *end note*]
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3908)
Before the lifetime of an object has started but after the storage which
the object will occupy has been allocated[21](#footnote-21 "For example, before the dynamic initialization of an object with static storage duration ([basic.start.dynamic]).") or after the lifetime of an object has ended and before the storage
which the object occupied is reused or released, any pointer that represents the address of
the storage location where the object will be or was located may be
used but only in limited ways[.](#7.sentence-1)
For an object under construction or destruction, see [[class.cdtor]](class.cdtor "11.9.5Construction and destruction")[.](#7.sentence-2)
Otherwise, such
a pointer refers to allocated
storage ([[basic.stc.dynamic.allocation]](basic.stc.dynamic.allocation "6.8.6.5.2Allocation functions")), and using the pointer as
if the pointer were of type void* is
well-defined[.](#7.sentence-3)
Indirection through such a pointer is permitted but the resulting lvalue may only be used in
limited ways, as described below[.](#7.sentence-4)
The
program has undefined behavior if
- [(7.1)](#7.1)
the pointer is used as the operand of a [*delete-expression*](expr.delete#nt:delete-expression "7.6.2.9Delete[expr.delete]"),
- [(7.2)](#7.2)
the pointer is used to access a non-static data member or call a
non-static member function of the object, or
- [(7.3)](#7.3)
the pointer is implicitly converted ([[conv.ptr]](conv.ptr "7.3.12Pointer conversions")) to a pointer
to a virtual base class, or
- [(7.4)](#7.4)
the pointer is used as the operand of a static_cast ([[expr.static.cast]](expr.static.cast "7.6.1.9Static cast")), except when the conversion
is to pointer to cv void, or to pointer to cv void and subsequently to pointer to cv char, cv unsigned char, or cv std::byte ([[cstddef.syn]](cstddef.syn "17.2.1Header <cstddef> synopsis")), or
- [(7.5)](#7.5)
the pointer is used as the operand of a dynamic_cast ([[expr.dynamic.cast]](expr.dynamic.cast "7.6.1.7Dynamic cast"))[.](#7.sentence-5)
[*Example [2](#example-2)*: #include <cstdlib>struct B {virtual void f(); void mutate(); virtual ~B();};
struct D1 : B { void f(); };struct D2 : B { void f(); };
void B::mutate() {new (this) D2; // reuses storage --- ends the lifetime of *this f(); // undefined behavior... = this; // OK, this points to valid memory}void g() {void* p = std::malloc(sizeof(D1) + sizeof(D2));
B* pb = new (p) D1;
pb->mutate(); *pb; // OK, pb points to valid memoryvoid* q = pb; // OK, pb points to valid memory pb->f(); // undefined behavior: lifetime of *pb has ended} — *end example*]
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3978)
Similarly, before the lifetime of an object has started but after the
storage which the object will occupy has been allocated or after the
lifetime of an object has ended and before the storage which the object
occupied is reused or released, any glvalue that refers to the original
object may be used but only in limited ways[.](#8.sentence-1)
For an object under construction or destruction, see [[class.cdtor]](class.cdtor "11.9.5Construction and destruction")[.](#8.sentence-2)
Otherwise, such
a glvalue refers to
allocated storage ([[basic.stc.dynamic.allocation]](basic.stc.dynamic.allocation "6.8.6.5.2Allocation functions")), and using the
properties of the glvalue that do not depend on its value is
well-defined[.](#8.sentence-3)
The program has undefined behavior if
- [(8.1)](#8.1)
the glvalue is used to access the object, or
- [(8.2)](#8.2)
the glvalue is used to call a non-static member function of the object, or
- [(8.3)](#8.3)
the glvalue is bound to a reference to a virtual base class ([[dcl.init.ref]](dcl.init.ref "9.5.4References")), or
- [(8.4)](#8.4)
the glvalue is used as the operand of adynamic_cast ([[expr.dynamic.cast]](expr.dynamic.cast "7.6.1.7Dynamic cast")) or as the operand oftypeid[.](#8.sentence-4)
[*Note [5](#note-5)*:
Therefore, undefined behavior results
if an object that is being constructed in one thread is referenced from another
thread without adequate synchronization[.](#8.sentence-5)
— *end note*]
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4005)
An object o1 is [*transparently replaceable*](#def:transparently_replaceable "6.8.4Lifetime[basic.life]") by an object o2 if
- [(9.1)](#9.1)
the storage that o2 occupies exactly overlays
the storage that o1 occupied, and
- [(9.2)](#9.2)
o1 and o2 are of the same type
(ignoring the top-level cv-qualifiers), and
- [(9.3)](#9.3)
o1 is not a const, complete object, and
- [(9.4)](#9.4)
neither o1 nor o2 is a potentially-overlapping subobject ([[intro.object]](intro.object "6.8.2Object model")), and
- [(9.5)](#9.5)
either o1 and o2 are both complete objects, oro1 and o2 are direct subobjects of objects p1 and p2, respectively,
and p1 is transparently replaceable by p2[.](#9.sentence-1)
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4024)
After the lifetime of an object has ended and before the storage which the
object occupied is reused or released, if a new object is created at the
storage location which the original object occupied and the original object was
transparently replaceable by the new object, a pointer that pointed to the
original object, a reference that referred to the original object, or the name
of the original object will automatically refer to the new object and, once the
lifetime of the new object has started, can be used to manipulate the new
object[.](#10.sentence-1)
[*Example [3](#example-3)*: struct C {int i; void f(); const C& operator=( const C& );};
const C& C::operator=( const C& other) {if ( this != &other ) {this->~C(); // lifetime of *this endsnew (this) C(other); // new object of type C created f(); // well-defined}return *this;} C c1;
C c2;
c1 = c2; // well-defined c1.f(); // well-defined; c1 refers to a new object of type C — *end example*]
[*Note [6](#note-6)*:
If these conditions are not met,
a pointer to the new object can be obtained from
a pointer that represents the address of its storage
by calling std::launder ([[ptr.launder]](ptr.launder "17.6.5Pointer optimization barrier"))[.](#10.sentence-2)
— *end note*]
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4064)
If a program ends the lifetime of an object of type T with
static ([[basic.stc.static]](basic.stc.static "6.8.6.2Static storage duration")), thread ([[basic.stc.thread]](basic.stc.thread "6.8.6.3Thread storage duration")),
or automatic ([[basic.stc.auto]](basic.stc.auto "6.8.6.4Automatic storage duration"))
storage duration and if T has a non-trivial destructor,[22](#footnote-22 "That is, an object for which a destructor will be called implicitly—upon exit from the block for an object with automatic storage duration, upon exit from the thread for an object with thread storage duration, or upon exit from the program for an object with static storage duration.") and another object of the original type does not occupy
that same storage location when the implicit destructor call takes
place, the behavior of the program is undefined[.](#11.sentence-1)
This is true
even if the block is exited with an exception[.](#11.sentence-2)
[*Example [4](#example-4)*: class T { };struct B {~B();};
void h() { B b; new (&b) T;} // undefined behavior at block exit — *end example*]
[12](#12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4095)
Creating a new object within the storage that a const, complete
object with static, thread, or automatic storage duration occupies,
or within the storage that such a const object used to occupy before
its lifetime ended, results in undefined behavior[.](#12.sentence-1)
[*Example [5](#example-5)*: struct B { B(); ~B();};
const B b;
void h() { b.~B(); new (const_cast<B*>(&b)) const B; // undefined behavior} — *end example*]
[21)](#footnote-21)[21)](#footnoteref-21)
For example, before the dynamic initialization of
an object with static storage duration ([[basic.start.dynamic]](basic.start.dynamic "6.10.3.3Dynamic initialization of non-block variables"))[.](#footnote-21.sentence-1)
[22)](#footnote-22)[22)](#footnoteref-22)
That
is, an object for which a destructor will be called
implicitly—upon exit from the block for an object with
automatic storage duration, upon exit from the thread for an object with
thread storage duration, or upon exit from the program for an object
with static storage duration[.](#footnote-22.sentence-1)

524
cppdraft/basic/link.md Normal file
View File

@@ -0,0 +1,524 @@
[basic.link]
# 6 Basics [[basic]](./#basic)
## 6.7 Program and linkage [basic.link]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2876)
A [*program*](#def:program "6.7Program and linkage[basic.link]") consists of one or more [translation units](lex.separate#def:translation_unit "5.1Separate translation[lex.separate]") linked together[.](#1.sentence-1)
A translation unit consists
of a sequence of declarations[.](#1.sentence-2)
[translation-unit:](#nt:translation-unit "6.7Program and linkage[basic.link]")
[*declaration-seq*](dcl.pre#nt:declaration-seq "9.1Preamble[dcl.pre]")opt
[*global-module-fragment*](module.global.frag#nt:global-module-fragment "10.4Global module fragment[module.global.frag]")opt [*module-declaration*](module.unit#nt:module-declaration "10.1Module units and purviews[module.unit]") [*declaration-seq*](dcl.pre#nt:declaration-seq "9.1Preamble[dcl.pre]")opt [*private-module-fragment*](module.private.frag#nt:private-module-fragment "10.5Private module fragment[module.private.frag]")opt
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2889)
A name has[*external linkage*](#def:linkage,external "6.7Program and linkage[basic.link]"),[*module linkage*](#def:linkage,module "6.7Program and linkage[basic.link]"),[*internal linkage*](#def:linkage,internal "6.7Program and linkage[basic.link]"), or[*no linkage*](#def:linkage,no "6.7Program and linkage[basic.link]"),
as determined by the rules below[.](#2.sentence-1)
[*Note [1](#note-1)*:
All declarations of an entity with a name with internal linkage
appear in the same translation unit[.](#2.sentence-2)
All declarations of an entity with module linkage
are attached to the same module[.](#2.sentence-3)
— *end note*]
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2904)
The name of an entity
that belongs to a [namespace scope](basic.scope.namespace "6.4.6Namespace scope[basic.scope.namespace]") has internal linkage if it is the name of
- [(3.1)](#3.1)
a variable, variable template, function, or function template that is
explicitly declared static; or
- [(3.2)](#3.2)
a non-template variable of non-volatile const-qualified type, unless
* [(3.2.1)](#3.2.1)
it is declared in the purview of a module interface unit
(outside the [*private-module-fragment*](module.private.frag#nt:private-module-fragment "10.5Private module fragment[module.private.frag]"), if any) or
module partition, or
* [(3.2.2)](#3.2.2)
it is explicitly declared extern, or
* [(3.2.3)](#3.2.3)
it is inline, or
* [(3.2.4)](#3.2.4)
it was previously declared and the prior declaration did
not have internal linkage; or
- [(3.3)](#3.3)
a data member of an anonymous union[.](#3.sentence-1)
[*Note [2](#note-2)*:
An instantiated variable template that has const-qualified type
can have external or module linkage, even if not declared extern[.](#3.sentence-2)
— *end note*]
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2937)
An unnamed namespace or a namespace declared directly or indirectly within an
unnamed namespace has internal linkage[.](#4.sentence-1)
All other namespaces have external linkage[.](#4.sentence-2)
The name of an entity that belongs to a namespace scope,
that has not been given internal linkage above,
and that is the name of
- [(4.1)](#4.1)
a variable; or
- [(4.2)](#4.2)
a function; or
- [(4.3)](#4.3)
a named class ([[class.pre]](class.pre "11.1Preamble")), or an unnamed class defined in a
typedef declaration in which the class has the typedef name for linkage
purposes ([[dcl.typedef]](dcl.typedef "9.2.4The typedef specifier")); or
- [(4.4)](#4.4)
a named [enumeration](dcl.enum "9.8.1Enumeration declarations[dcl.enum]"), or an unnamed enumeration defined
in a typedef declaration in which the enumeration has the typedef name
for linkage purposes ([[dcl.typedef]](dcl.typedef "9.2.4The typedef specifier")); or
- [(4.5)](#4.5)
an unnamed enumeration
that has an enumerator as a name for linkage purposes ([[dcl.enum]](dcl.enum "9.8.1Enumeration declarations")); or
- [(4.6)](#4.6)
a template
has its linkage determined as follows:
- [(4.7)](#4.7)
if the entity is a function or function template
first declared in a friend declaration and
that declaration is a definition and
the enclosing class is defined within an [*export-declaration*](module.interface#nt:export-declaration "10.2Export declaration[module.interface]"),
the name has the same linkage, if any,
as the name of the enclosing class ([[class.friend]](class.friend "11.8.4Friends"));
- [(4.8)](#4.8)
otherwise,if the entity is a function or function template
declared in a friend declaration and
a corresponding non-friend declaration is reachable,
the name has the linkage determined from that prior declaration,
- [(4.9)](#4.9)
otherwise,
if the enclosing namespace has internal linkage,
the name has internal linkage;
- [(4.10)](#4.10)
otherwise,
if the declaration of the name is
attached to a named module ([[module.unit]](module.unit "10.1Module units and purviews"))
and is not exported ([[module.interface]](module.interface "10.2Export declaration")),
the name has module linkage;
- [(4.11)](#4.11)
otherwise,
the name has external linkage[.](#4.sentence-3)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2994)
In addition,
a member function,
a static data member,
a named class or enumeration that inhabits a class scope, or
an unnamed class or enumeration defined in a typedef declaration
that inhabits a class scope
such that the class or enumeration
has the typedef name for linkage purposes ([[dcl.typedef]](dcl.typedef "9.2.4The typedef specifier")),
has the same linkage, if any, as the name of the class of which it is a member[.](#5.sentence-1)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3005)
[*Example [1](#example-1)*: static void f();extern "C" void h();static int i = 0; // #1void q() {extern void f(); // internal linkageextern void g(); // ::g, external linkageextern void h(); // C language linkageint i; // #2: i has no linkage{extern void f(); // internal linkageextern int i; // #3: internal linkage}}
Even though the declaration at line #2 hides the declaration at line #1,
the declaration at line #3 still redeclares #1 and receives internal linkage[.](#6.sentence-1)
— *end example*]
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3026)
Names not covered by these rules have no linkage[.](#7.sentence-1)
Moreover, except as
noted, a name declared at [block scope](basic.scope.block#def:scope,block "6.4.3Block scope[basic.scope.block]") has no
linkage[.](#7.sentence-2)
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3032)
Two declarations of entities declare the same entity
if, considering declarations of unnamed types to introduce their names
for linkage purposes, if any ([[dcl.typedef]](dcl.typedef "9.2.4The typedef specifier"), [[dcl.enum]](dcl.enum "9.8.1Enumeration declarations")),
they correspond ([[basic.scope.scope]](basic.scope.scope "6.4.1General")),
have the same target scope that is not a function or template parameter scope,
neither is a name-independent declaration,
and either
- [(8.1)](#8.1)
they appear in the same translation unit, or
- [(8.2)](#8.2)
they both declare type aliases or namespace aliases that have the same underlying entity, or
- [(8.3)](#8.3)
they both declare names with module linkage and are attached to the same module, or
- [(8.4)](#8.4)
they both declare names with external linkage[.](#8.sentence-1)
[*Note [3](#note-3)*:
There are other circumstances in which declarations declare
the same entity ([[dcl.link]](dcl.link "9.12Linkage specifications"), [[temp.type]](temp.type "13.6Type equivalence"), [[temp.spec.partial]](temp.spec.partial "13.7.6Partial specialization"))[.](#8.sentence-2)
— *end note*]
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3055)
If a declaration H that declares a name with internal linkage
precedes a declaration D in another translation unit U and
would declare the same entity as D if it appeared in U,
the program is ill-formed[.](#9.sentence-1)
[*Note [4](#note-4)*:
Such an H can appear only in a header unit[.](#9.sentence-2)
— *end note*]
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3064)
If two declarations of an entity are
attached to different modules, the program is ill-formed;
no diagnostic is required if neither is reachable from the other[.](#10.sentence-1)
[*Example [2](#example-2)*:
"decls.h":int f(); // #1, attached to the global moduleint g(); // #2, attached to the global module
Module interface of M:module;#include "decls.h"export module M;export using ::f; // OK, does not declare an entity, exports #1int g(); // error: matches #2, but attached to Mexport int h(); // #3export int k(); // #4
Other translation unit:import M;static int h(); // error: matches #3int k(); // error: matches #4 — *end example*]
As a consequence of these rules,
all declarations of an entity are attached to the same module;
the entity is said to be [*attached*](#def:attached,entity "6.7Program and linkage[basic.link]") to that module[.](#10.sentence-2)
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3094)
For any two declarations of an entity E:
- [(11.1)](#11.1)
If one declares E to be a variable or function,
the other shall declare E as one of the same type[.](#11.1.sentence-1)
- [(11.2)](#11.2)
If one declares E to be an enumerator, the other shall do so[.](#11.2.sentence-1)
- [(11.3)](#11.3)
If one declares E to be a namespace, the other shall do so[.](#11.3.sentence-1)
- [(11.4)](#11.4)
If one declares E to be a type,
the other shall declare E to be a type of the same kind ([[dcl.type.elab]](dcl.type.elab "9.2.9.5Elaborated type specifiers"))[.](#11.4.sentence-1)
- [(11.5)](#11.5)
If one declares E to be a class template,
the other shall do so with the same kind and
an equivalent [*template-head*](temp.pre#nt:template-head "13.1Preamble[temp.pre]") ([[temp.over.link]](temp.over.link "13.7.7.2Function template overloading"))[.](#11.5.sentence-1)
[*Note [5](#note-5)*:
The declarations can supply different default template arguments[.](#11.5.sentence-2)
— *end note*]
- [(11.6)](#11.6)
If one declares E to be a function template or
a (partial specialization of a) variable template,
the other shall declare E to be one
with an equivalent [*template-head*](temp.pre#nt:template-head "13.1Preamble[temp.pre]") and type[.](#11.6.sentence-1)
- [(11.7)](#11.7)
If one declares E to be an alias template,
the other shall declare E to be one with
an equivalent [*template-head*](temp.pre#nt:template-head "13.1Preamble[temp.pre]") and [*defining-type-id*](dcl.name#nt:defining-type-id "9.3.2Type names[dcl.name]")[.](#11.7.sentence-1)
- [(11.8)](#11.8)
If one declares E to be a concept, the other shall do so[.](#11.8.sentence-1)
Types are compared after all adjustments of types (during which
typedefs ([[dcl.typedef]](dcl.typedef "9.2.4The typedef specifier")) are replaced by their definitions);
declarations for an array
object can specify array types that differ by the presence or absence of
a major array bound ([[dcl.array]](dcl.array "9.3.4.5Arrays"))[.](#11.sentence-2)
No diagnostic is required if neither declaration is reachable from the other[.](#11.sentence-3)
[*Example [3](#example-3)*: int f(int x, int x); // error: different entities for xvoid g(); // #1void g(int); // OK, different entity from #1int g(); // error: same entity as #1 with different typevoid h(); // #2namespace h {} // error: same entity as #2, but not a function — *end example*]
[12](#12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3145)
[*Note [6](#note-6)*:
Linkage to non-C++ declarations can be achieved using a[*linkage-specification*](dcl.link#nt:linkage-specification "9.12Linkage specifications[dcl.link]") ([[dcl.link]](dcl.link "9.12Linkage specifications"))[.](#12.sentence-1)
— *end note*]
[13](#13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3152)
A declaration D [*names*](#def:name "6.7Program and linkage[basic.link]") an entity E if
- [(13.1)](#13.1)
D contains a [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1General[expr.prim.lambda.general]") whose closure type is E,
- [(13.2)](#13.2)
D contains
a [*reflect-expression*](expr.reflect#nt:reflect-expression "7.6.2.10The reflection operator[expr.reflect]") or a [*splice-specifier*](basic.splice#nt:splice-specifier "6.6Splice specifiers[basic.splice]") that, respectively, represents or designates E,
- [(13.3)](#13.3)
D is an injected declaration ([[expr.const]](expr.const "7.7Constant expressions"))
whose characteristic sequence contains a reflection
that represents
a data member description (T, N, A, W, NUA) ([[class.mem.general]](class.mem.general "11.4.1General"))
for which T is E,
- [(13.4)](#13.4)
E is not a function or function template and D contains an[*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1General[expr.prim.id.general]"),[*type-specifier*](dcl.type.general#nt:type-specifier "9.2.9.1General[dcl.type.general]"),[*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]"),[*template-name*](temp.names#nt:template-name "13.3Names of template specializations[temp.names]"), or[*concept-name*](temp.concept#nt:concept-name "13.7.9Concept definitions[temp.concept]") denoting E, or
- [(13.5)](#13.5)
E is a function or function template andD contains an expression that names E ([[basic.def.odr]](basic.def.odr "6.3One-definition rule")) or
an [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1General[expr.prim.id.general]") that refers to a set of overloads that contains E[.](#13.sentence-1)
[*Note [7](#note-7)*:
Non-dependent names in an instantiated declaration
do not refer to a set of overloads ([[temp.res]](temp.res "13.8Name resolution"))[.](#13.5.sentence-2)
— *end note*]
[14](#14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3186)
A declaration is an [*exposure*](#def:exposure "6.7Program and linkage[basic.link]") if it either names a TU-local entity (defined below), ignoring
- [(14.1)](#14.1)
the [*function-body*](dcl.fct.def.general#nt:function-body "9.6.1General[dcl.fct.def.general]") for a non-inline function or function template
(but not the deduced return type
for a (possibly instantiated) definition of a function
with a declared return type that uses a placeholder type ([[dcl.spec.auto]](dcl.spec.auto "9.2.9.7Placeholder type specifiers"))),
- [(14.2)](#14.2)
the [*initializer*](dcl.init.general#nt:initializer "9.5.1General[dcl.init.general]") for a variable or variable template (but not the variable's type),
- [(14.3)](#14.3)
friend declarations in a class definition, and
- [(14.4)](#14.4)
any reference to a non-volatile const object or reference
with internal or no linkage initialized with a constant expression
that is not an odr-use ([[basic.def.odr]](basic.def.odr#term.odr.use "6.3One-definition rule")),
or defines a constexpr variable initialized to a TU-local value (defined below)[.](#14.sentence-1)
[*Note [8](#note-8)*:
An inline function template can be an exposure even though
certain explicit specializations of it would be usable in other translation units[.](#14.sentence-2)
— *end note*]
[15](#15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3212)
An entity is [*TU-local*](#def:TU-local,entity "6.7Program and linkage[basic.link]") if it is
- [(15.1)](#15.1)
a type, type alias, namespace, namespace alias, function, variable, or template that
* [(15.1.1)](#15.1.1)
has a name with internal linkage, or
* [(15.1.2)](#15.1.2)
does not have a name with linkage and is declared,
or introduced by a [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1General[expr.prim.lambda.general]"),
within the definition of a TU-local entity,
- [(15.2)](#15.2)
a type with no name that is defined outside a[*class-specifier*](class.pre#nt:class-specifier "11.1Preamble[class.pre]"),
function body, or[*initializer*](dcl.init.general#nt:initializer "9.5.1General[dcl.init.general]") or is introduced by a [*defining-type-specifier*](dcl.type.general#nt:defining-type-specifier "9.2.9.1General[dcl.type.general]") that is used to declare only TU-local entities,
- [(15.3)](#15.3)
a specialization of a TU-local template,
- [(15.4)](#15.4)
a specialization of a template with any TU-local template argument, or
- [(15.5)](#15.5)
a specialization of a template
whose (possibly instantiated) declaration is an exposure[.](#15.sentence-1)
[*Note [9](#note-9)*:
A specialization can be produced by implicit or explicit instantiation[.](#15.5.sentence-2)
— *end note*]
[16](#16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3244)
A value or object is [*TU-local*](#def:TU-local,value_or_object "6.7Program and linkage[basic.link]") if either
- [(16.1)](#16.1)
it is of TU-local type,
- [(16.2)](#16.2)
it is, or is a pointer to,
a TU-local function or the object associated with a TU-local variable,
- [(16.3)](#16.3)
it is an object of class or array type and
any of its subobjects or
any of the objects or functions
to which its non-static data members of reference type refer
is TU-local and is usable in constant expressions, or
- [(16.4)](#16.4)
it is a reflection value ([[basic.fundamental]](basic.fundamental "6.9.2Fundamental types")) that represents
* [(16.4.1)](#16.4.1)
an entity, value, or object that is TU-local,
* [(16.4.2)](#16.4.2)
a direct base class relationship (D, B) ([[class.derived.general]](class.derived.general "11.7.1General"))
for which either D or B is TU-local, or
* [(16.4.3)](#16.4.3)
a data member description (T, N, A, W, NUA) ([[class.mem.general]](class.mem.general "11.4.1General"))
for which T is TU-local[.](#16.sentence-1)
[17](#17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3272)
If a (possibly instantiated) declaration of, or a deduction guide for,
a non-TU-local entity in a module interface unit
(outside the [*private-module-fragment*](module.private.frag#nt:private-module-fragment "10.5Private module fragment[module.private.frag]"), if any) or
module partition ([[module.unit]](module.unit "10.1Module units and purviews")) is an exposure,
the program is ill-formed[.](#17.sentence-1)
Such a declaration in any other context is deprecated ([[depr.local]](depr.local "D.2Non-local use of TU-local entities"))[.](#17.sentence-2)
[18](#18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3280)
If a declaration that appears in one translation unit
names a TU-local entity declared
in another translation unit that is not a header unit,
the program is ill-formed[.](#18.sentence-1)
A declaration instantiated for a template specialization ([[temp.spec]](temp.spec "13.9Template instantiation and specialization"))
appears at the point of instantiation of the specialization ([[temp.point]](temp.point "13.8.4.1Point of instantiation"))[.](#18.sentence-2)
[19](#19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L3288)
[*Example [4](#example-4)*:
Translation unit #1:export module A;static void f() {}inline void it() { f(); } // error: is an exposure of fstatic inline void its() { f(); } // OKtemplate<int> void g() { its(); } // OKtemplate void g<0>();
decltype(f) *fp; // error: f (though not its type) is TU-localauto &fr = f; // OKconstexpr auto &fr2 = fr; // error: is an exposure of fconstexpr static auto fp2 = fr; // OKstruct S { void (&ref)(); } s{f}; // OK, value is TU-localconstexpr extern struct W { S &s; } wrap{s}; // OK, value is not TU-localstatic auto x = []{f();}; // OKauto x2 = x; // error: the closure type is TU-localint y = ([]{f();}(),0); // error: the closure type is not TU-localint y2 = (x,0); // OKnamespace N {struct A {}; void adl(A); static void adl(int);}void adl(double);
inline void h(auto x) { adl(x); } // OK, but certain specializations are exposuresconstexpr std::meta::info r1 = ^^g<0>; // OKnamespace N2 {static constexpr std::meta::info r2 = ^^g<1>; // OK, r2 is TU-local}constexpr std::meta::info r3 = ^^f; // error: r3 is an exposure of fconstexpr auto ctx = std::meta::access_context::current();constexpr std::meta::info r4 = std::meta::members_of(^^N2, ctx)[0]; // error: r4 is an exposure of N2::r2
Translation unit #2:module A;void other() { g<0>(); // OK, specialization is explicitly instantiated g<1>(); // error: instantiation uses TU-local its h(N::A{}); // error: overload set contains TU-local N::adl(int) h(0); // OK, calls adl(double) adl(N::A{}); // OK; N::adl(int) not found, calls N::adl(N::A) fr(); // OK, calls fconstexpr auto ptr = fr; // error: fr is not usable in constant expressions here} — *end example*]

948
cppdraft/basic/lookup.md Normal file
View File

@@ -0,0 +1,948 @@
[basic.lookup]
# 6 Basics [[basic]](./#basic)
## 6.5 Name lookup [basic.lookup]
### [6.5.1](#general) General [[basic.lookup.general]](basic.lookup.general)
[1](#general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1624)
[*Name lookup*](#def:lookup,name "6.5.1General[basic.lookup.general]") associates the use of a name
with a set of declarations ([[basic.def]](basic.def "6.2Declarations and definitions")) of that name[.](#general-1.sentence-1)
The name lookup rules apply uniformly to all names (including[*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4The typedef specifier[dcl.typedef]")*s* ([[dcl.typedef]](dcl.typedef "9.2.4The typedef specifier")),[*namespace-name*](namespace.def.general#nt:namespace-name "9.9.2.1General[namespace.def.general]")*s* ([[basic.namespace]](basic.namespace "9.9Namespaces")), and[*class-name*](class.pre#nt:class-name "11.1Preamble[class.pre]")*s* ([[class.name]](class.name "11.3Class names"))) wherever the grammar allows
such names in the context discussed by a particular rule[.](#general-1.sentence-2)
Unless otherwise specified,
the program is ill-formed if no declarations are found[.](#general-1.sentence-3)
If the declarations found by name lookup
all denote functions or function templates,
the declarations are said to form an [*overload set*](#def:overload_set "6.5.1General[basic.lookup.general]")[.](#general-1.sentence-4)
Otherwise,
if the declarations found by name lookup do not all denote the same entity,they are [*ambiguous*](#def:ambiguous "6.5.1General[basic.lookup.general]") and the program is ill-formed[.](#general-1.sentence-5)
Overload resolution ([[over.match]](over.match "12.2Overload resolution"), [[over.over]](over.over "12.3Address of an overload set"))
takes place after name lookup has succeeded[.](#general-1.sentence-6)
The access rules ([[class.access]](class.access "11.8Member access control"))
are considered only once name lookup and
function overload resolution (if applicable) have succeeded[.](#general-1.sentence-7)
Only after
name lookup, function overload resolution (if applicable) and access
checking have succeeded
are the semantic properties introduced by the declarations
used in further processing[.](#general-1.sentence-8)
[2](#general-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1650)
A program point P is said to follow
any declaration in the same translation unit
whose locus ([[basic.scope.pdecl]](basic.scope.pdecl "6.4.2Point of declaration")) is before P[.](#general-2.sentence-1)
[*Note [1](#general-note-1)*:
The declaration might appear in a scope that does not contain P[.](#general-2.sentence-2)
— *end note*]
A declaration X [*precedes*](#def:declaration,precede "6.5.1General[basic.lookup.general]") a program point P in a translation unit L if P follows X, X inhabits a class scope and is reachable from P, or
else X appears in a translation unit D and
- [(2.1)](#general-2.1)
P follows
a [*module-import-declaration*](module.import#nt:module-import-declaration "10.3Import declaration[module.import]") or [*module-declaration*](module.unit#nt:module-declaration "10.1Module units and purviews[module.unit]") that imports D (directly or indirectly), and
- [(2.2)](#general-2.2)
X appears after the [*module-declaration*](module.unit#nt:module-declaration "10.1Module units and purviews[module.unit]") in D (if any) and
before the [*private-module-fragment*](module.private.frag#nt:private-module-fragment "10.5Private module fragment[module.private.frag]") in D (if any), and
- [(2.3)](#general-2.3)
either X is exported or else D and L are part of the same module andX does not inhabit a namespace with internal linkage or
declare a name with internal linkage[.](#general-2.sentence-3)
[*Note [2](#general-note-2)*:
Names declared by a [*using-declaration*](namespace.udecl#nt:using-declaration "9.10The using declaration[namespace.udecl]") have no linkage[.](#general-2.3.sentence-2)
— *end note*]
[*Note [3](#general-note-3)*:
A [*module-import-declaration*](module.import#nt:module-import-declaration "10.3Import declaration[module.import]") imports both
the named translation unit(s) and
any modules named by exported[*module-import-declaration*](module.import#nt:module-import-declaration "10.3Import declaration[module.import]")*s* within them,
recursively[.](#general-2.sentence-4)
[*Example [1](#general-example-1)*:
Translation unit #1:export module Q;export int sq(int i) { return i*i; }
Translation unit #2:export module R;export import Q;
Translation unit #3:import R;int main() { return sq(9); } // OK, sq from module Q — *end example*]
— *end note*]
[3](#general-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1702)
A [*single search*](#def:search,single "6.5.1General[basic.lookup.general]") in a scope S for a name N from a program point P finds all declarations that precede P to which any name that is the same as N ([[basic.pre]](basic.pre "6.1Preamble")) is bound in S[.](#general-3.sentence-1)
If any such declaration is a [*using-declarator*](namespace.udecl#nt:using-declarator "9.10The using declaration[namespace.udecl]") whose terminal name ([[expr.prim.id.unqual]](expr.prim.id.unqual "7.5.5.2Unqualified names"))
is not dependent ([[temp.dep.type]](temp.dep.type "13.8.3.2Dependent types")),
it is replaced by the declarations named by
the [*using-declarator*](namespace.udecl#nt:using-declarator "9.10The using declaration[namespace.udecl]") ([[namespace.udecl]](namespace.udecl "9.10The using declaration"))[.](#general-3.sentence-2)
[4](#general-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1714)
In certain contexts, only certain kinds of declarations are included[.](#general-4.sentence-1)
After any such restriction, any declarations of classes or enumerations are discarded if any other declarations are found[.](#general-4.sentence-2)
[*Note [4](#general-note-4)*:
A type (but not a type alias or template)
is therefore hidden by any other entity in its scope[.](#general-4.sentence-3)
— *end note*]
However, if a lookup is [*type-only*](#def:lookup,type-only "6.5.1General[basic.lookup.general]"),
only declarations of
types and templates whose specializations are types are considered;
furthermore, if declarations
of a type alias and of its underlying entity are found,
the declaration of the type alias is discarded
instead of the type declaration[.](#general-4.sentence-4)
### [6.5.2](#class.member.lookup) Member name lookup [[class.member.lookup]](class.member.lookup)
[1](#class.member.lookup-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1735)
A [*search*](#def:search "6.5.2Member name lookup[class.member.lookup]") in a scope X for a name M from a program point P is a single search in X for M from P unless X is the scope of a class or class template T, in which case the
following steps define the result of the search[.](#class.member.lookup-1.sentence-1)
[*Note [1](#class.member.lookup-note-1)*:
The result differs only
if M is a [*conversion-function-id*](class.conv.fct#nt:conversion-function-id "11.4.8.3Conversion functions[class.conv.fct]") or
if the single search would find nothing[.](#class.member.lookup-1.sentence-2)
— *end note*]
[2](#class.member.lookup-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1747)
The [*lookup set*](#def:lookup_set "6.5.2Member name lookup[class.member.lookup]") for a name N in a class or class template C, called S(N,C),
consists of two component sets:
the [*declaration set*](#def:declaration_set), a set of members named N; and
the [*subobject set*](#def:subobject_set),
a set of subobjects where declarations of these members were found
(possibly via [*using-declaration*](namespace.udecl#nt:using-declaration "9.10The using declaration[namespace.udecl]")*s*)[.](#class.member.lookup-2.sentence-1)
In the declaration set, type declarations (including injected-class-names)
are replaced by the types they designate[.](#class.member.lookup-2.sentence-2)
S(N,C) is calculated as follows:
[3](#class.member.lookup-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1757)
The declaration set is the result of
a single search in the scope of C for N from immediately after the [*class-specifier*](class.pre#nt:class-specifier "11.1Preamble[class.pre]") of C if P is in a complete-class context of C or
from P otherwise[.](#class.member.lookup-3.sentence-1)
If the resulting declaration set is not empty, the subobject set
contains C itself, and calculation is complete[.](#class.member.lookup-3.sentence-2)
[4](#class.member.lookup-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1766)
Otherwise (i.e., C does not contain a declaration of N or the resulting declaration set is empty), S(N,C) is initially empty[.](#class.member.lookup-4.sentence-1)
Calculate the lookup set for N in each direct non-dependent ([[temp.dep.type]](temp.dep.type "13.8.3.2Dependent types")) base class subobject Bi, and
merge each such lookup set S(N,Bi) in turn into S(N,C)[.](#class.member.lookup-4.sentence-2)
[*Note [2](#class.member.lookup-note-2)*:
If C is incomplete,
only base classes whose [*base-specifier*](class.derived.general#nt:base-specifier "11.7.1General[class.derived.general]") appears before P are considered[.](#class.member.lookup-4.sentence-3)
If C is an instantiated class, its base classes are not dependent[.](#class.member.lookup-4.sentence-4)
— *end note*]
[5](#class.member.lookup-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1779)
The following steps define the result of merging lookup set S(N,Bi) into the intermediate S(N,C):
- [(5.1)](#class.member.lookup-5.1)
If each of the subobject members of S(N,Bi) is a base class
subobject of at least one of the subobject members of S(N,C), or ifS(N,Bi) is empty, S(N,C) is unchanged and the merge is complete[.](#class.member.lookup-5.1.sentence-1)
Conversely, if each of the subobject members of S(N,C) is a base class
subobject of at least one of the subobject members of S(N,Bi), or ifS(N,C) is empty, the new S(N,C) is a copy of S(N,Bi)[.](#class.member.lookup-5.1.sentence-2)
- [(5.2)](#class.member.lookup-5.2)
Otherwise, if the declaration sets of S(N,Bi) and S(N,C) differ, the merge is ambiguous: the new S(N,C) is a lookup set with an
invalid declaration set and the union of the subobject sets[.](#class.member.lookup-5.2.sentence-1)
In
subsequent merges, an invalid declaration set is considered different
from any other[.](#class.member.lookup-5.2.sentence-2)
- [(5.3)](#class.member.lookup-5.3)
Otherwise, the new S(N,C) is a lookup set with the shared set of
declarations and the union of the subobject sets[.](#class.member.lookup-5.3.sentence-1)
[6](#class.member.lookup-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1801)
The result of the search is the declaration set of S(M,T)[.](#class.member.lookup-6.sentence-1)
If it is an invalid set, the program is ill-formed[.](#class.member.lookup-6.sentence-2)
If it differs from the result of a search in T for M in a complete-class context ([[class.mem]](class.mem "11.4Class members")) of T,
the program is ill-formed, no diagnostic required[.](#class.member.lookup-6.sentence-3)
[*Example [1](#class.member.lookup-example-1)*: struct A { int x; }; // S(x,A) = { { A::x }, { A } }struct B { float x; }; // S(x,B) = { { B::x }, { B } }struct C: public A, public B { }; // S(x,C) = { invalid, { A in C, B in C } }struct D: public virtual C { }; // S(x,D) = S(x,C)struct E: public virtual C { char x; }; // S(x,E) = { { E::x }, { E } }struct F: public D, public E { }; // S(x,F) = S(x,E)int main() { F f;
f.x = 0; // OK, lookup finds E::x}
S(x,F) is unambiguous because the A and B base
class subobjects of D are also base class subobjects of E, soS(x,D) is discarded in the first merge step[.](#class.member.lookup-6.sentence-4)
— *end example*]
[7](#class.member.lookup-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1826)
If M is a non-dependent [*conversion-function-id*](class.conv.fct#nt:conversion-function-id "11.4.8.3Conversion functions[class.conv.fct]"),
conversion function templates that are members of T are considered[.](#class.member.lookup-7.sentence-1)
For each such template F, the lookup set S(t,T) is constructed,
considering a function template declaration to have the name t only if it corresponds to a declaration of F ([[basic.scope.scope]](basic.scope.scope "6.4.1General"))[.](#class.member.lookup-7.sentence-2)
The members of the declaration set of each such lookup set,
which shall not be an invalid set, are included in the result[.](#class.member.lookup-7.sentence-3)
[*Note [3](#class.member.lookup-note-3)*:
Overload resolution will discard those
that cannot convert to the type specified by M ([[temp.over]](temp.over "13.10.4Overload resolution"))[.](#class.member.lookup-7.sentence-4)
— *end note*]
[8](#class.member.lookup-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1839)
[*Note [4](#class.member.lookup-note-4)*:
A static member, a nested type or an enumerator defined in a base classT can unambiguously be found even if an object has more than one
base class subobject of type T[.](#class.member.lookup-8.sentence-1)
Two base class subobjects share
the non-static member subobjects of their common virtual base classes[.](#class.member.lookup-8.sentence-2)
— *end note*]
[*Example [2](#class.member.lookup-example-2)*: struct V {int v;};struct A {int a; static int s; enum { e };};struct B : A, virtual V { };struct C : A, virtual V { };struct D : B, C { };
void f(D* pd) { pd->v++; // OK, only one v (virtual) pd->s++; // OK, only one s (static)int i = pd->e; // OK, only one e (enumerator) pd->a++; // error: ambiguous: two as in D} — *end example*]
[9](#class.member.lookup-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1869)
[*Note [5](#class.member.lookup-note-5)*:
When virtual base classes are used, a hidden declaration can be reached
along a path through the subobject lattice that does not pass through
the hiding declaration[.](#class.member.lookup-9.sentence-1)
This is not an ambiguity[.](#class.member.lookup-9.sentence-2)
The identical use with
non-virtual base classes is an ambiguity; in that case there is no
unique instance of the name that hides all the others[.](#class.member.lookup-9.sentence-3)
— *end note*]
[*Example [3](#class.member.lookup-example-3)*: struct V { int f(); int x; };struct W { int g(); int y; };struct B : virtual V, W {int f(); int x; int g(); int y;};struct C : virtual V, W { };
struct D : B, C { void glorp(); };
![SVG Image](data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwLjAwIDAuMDAgMzg2LjAwIDE0MC4wMCIgd2lkdGg9IjM4NnB0IiBoZWlnaHQ9IjE0MHB0Ij4KPGcgY2xhc3M9ImdyYXBoIj4KdmlydAoKPGcgY2xhc3M9Im5vZGUiPgpXMQpXCjwvZz4KCjxnIGNsYXNzPSJub2RlIj4KVgpWCjwvZz4KCjxnIGNsYXNzPSJub2RlIj4KVzIKVwo8L2c+Cgo8ZyBjbGFzcz0ibm9kZSI+CkIKQgo8L2c+Cgo8ZyBjbGFzcz0iZWRnZSI+CkItJmd0O1cxCjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGQ9Ik05NC4yNiwtNzYuMTZDODEuODUsLTg0LjQzIDYzLjM3LC05Ni43NSA0OC45MiwtMTA2LjM4IiAvPgo8cG9seWdvbiBmaWxsPSJibGFjayIgc3Ryb2tlPSJibGFjayIgLz4KPC9nPgoKPGcgY2xhc3M9ImVkZ2UiPgpCLSZndDtWCjxwYXRoIHN0cm9rZT0iYmxhY2siIGZpbGw9Im5vbmUiIGQ9Ik0xMjEuNzQsLTc2LjE2QzEzNC4xNSwtODQuNDMgMTUyLjYzLC05Ni43NSAxNjcuMDgsLTEwNi4zOCIgLz4KPHBvbHlnb24gZmlsbD0iYmxhY2siIHN0cm9rZT0iYmxhY2siIC8+CjwvZz4KCjxnIGNsYXNzPSJub2RlIj4KQwpDCjwvZz4KCjxnIGNsYXNzPSJlZGdlIj4KQy0mZ3Q7Vgo8cGF0aCBmaWxsPSJub25lIiBkPSJNMjU2LjI2LC03Ni4xNkMyNDMuODUsLTg0LjQzIDIyNS4zNywtOTYuNzUgMjEwLjkyLC0xMDYuMzgiIHN0cm9rZT0iYmxhY2siIC8+Cjxwb2x5Z29uIGZpbGw9ImJsYWNrIiBzdHJva2U9ImJsYWNrIiAvPgo8L2c+Cgo8ZyBjbGFzcz0iZWRnZSI+CkMtJmd0O1cyCjxwYXRoIGZpbGw9Im5vbmUiIGQ9Ik0yODMuNzQsLTc2LjE2QzI5Ni4xNSwtODQuNDMgMzE0LjYzLC05Ni43NSAzMjkuMDgsLTEwNi4zOCIgc3Ryb2tlPSJibGFjayIgLz4KPHBvbHlnb24gZmlsbD0iYmxhY2siIHN0cm9rZT0iYmxhY2siIC8+CjwvZz4KCjxnIGNsYXNzPSJub2RlIj4KRApECjwvZz4KCjxnIGNsYXNzPSJlZGdlIj4KRC0mZ3Q7Qgo8cGF0aCBzdHJva2U9ImJsYWNrIiBmaWxsPSJub25lIiBkPSJNMTc1LjI2LC0yMC4xNkMxNjIuODUsLTI4LjQzIDE0NC4zNywtNDAuNzUgMTI5LjkyLC01MC4zOCIgLz4KPHBvbHlnb24gZmlsbD0iYmxhY2siIHN0cm9rZT0iYmxhY2siIC8+CjwvZz4KCjxnIGNsYXNzPSJlZGdlIj4KRC0mZ3Q7Qwo8cGF0aCBzdHJva2U9ImJsYWNrIiBkPSJNMjAyLjc0LC0yMC4xNkMyMTUuMTUsLTI4LjQzIDIzMy42MywtNDAuNzUgMjQ4LjA4LC01MC4zOCIgZmlsbD0ibm9uZSIgLz4KPHBvbHlnb24gZmlsbD0iYmxhY2siIHN0cm9rZT0iYmxhY2siIC8+CjwvZz4KPC9nPgo8L3N2Zz4=)
Figure [1](#fig:class.lookup) — Name lookup [[fig:class.lookup]](./fig:class.lookup)
As illustrated in Figure [1](#fig:class.lookup),
the names declared in V and the left-hand instance of W are hidden by those in B, but the names declared in the
right-hand instance of W are not hidden at all[.](#class.member.lookup-9.sentence-4)
void D::glorp() { x++; // OK, B::x hides V::x f(); // OK, B::f() hides V::f() y++; // error: B::y and C's W::y g(); // error: B::g() and C's W::g()} — *end example*]
[10](#class.member.lookup-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1912)
An explicit or implicit conversion from a pointer to or
an expression designating an object
of a
derived class to a pointer or reference to one of its base classes shall
unambiguously refer to a unique object representing the base class[.](#class.member.lookup-10.sentence-1)
[*Example [4](#class.member.lookup-example-4)*: struct V { };struct A { };struct B : A, virtual V { };struct C : A, virtual V { };struct D : B, C { };
void g() { D d;
B* pb = &d;
A* pa = &d; // error: ambiguous: C's A or B's A? V* pv = &d; // OK, only one V subobject} — *end example*]
[11](#class.member.lookup-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1935)
[*Note [6](#class.member.lookup-note-6)*:
Even if the result of name lookup is unambiguous, use of a name found in
multiple subobjects might still be
ambiguous ([[conv.mem]](conv.mem "7.3.13Pointer-to-member conversions"), [[expr.ref]](expr.ref "7.6.1.5Class member access"), [[class.access.base]](class.access.base "11.8.3Accessibility of base classes and base class members"))[.](#class.member.lookup-11.sentence-1)
— *end note*]
[*Example [5](#class.member.lookup-example-5)*: struct B1 {void f(); static void f(int); int i;};struct B2 {void f(double);};struct I1: B1 { };struct I2: B1 { };
struct D: I1, I2, B2 {using B1::f; using B2::f; void g() { f(); // Ambiguous conversion of this f(0); // Unambiguous (static) f(0.0); // Unambiguous (only one B2)int B1::* mpB1 = &D::i; // Unambiguousint D::* mpD = &D::i; // Ambiguous conversion}}; — *end example*]
### [6.5.3](#unqual) Unqualified name lookup [[basic.lookup.unqual]](basic.lookup.unqual)
[1](#unqual-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1972)
A [*using-directive*](namespace.udir#nt:using-directive "9.9.4Using namespace directive[namespace.udir]") is[*active*](#def:active) in a scope S at a program point P if it precedes P and inhabits either S or
the scope of a namespace nominated by a [*using-directive*](namespace.udir#nt:using-directive "9.9.4Using namespace directive[namespace.udir]") that is active in S at P[.](#unqual-1.sentence-1)
[2](#unqual-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1979)
An [*unqualified search*](#def:unqualified_search) in a scope S from a program point P includes the results of searches from P in
- [(2.1)](#unqual-2.1)
S, and
- [(2.2)](#unqual-2.2)
for any scope U that contains P and is or is contained by S,
each namespace contained by S that is nominated by
a [*using-directive*](namespace.udir#nt:using-directive "9.9.4Using namespace directive[namespace.udir]") that is active in U at P[.](#unqual-2.sentence-1)
If no declarations are found,
the results of the unqualified search are
the results of an unqualified search in the parent scope of S, if any,
from P[.](#unqual-2.sentence-2)
[*Note [1](#unqual-note-1)*:
When a class scope is searched,
the scopes of its base classes are also searched ([[class.member.lookup]](#class.member.lookup "6.5.2Member name lookup"))[.](#unqual-2.sentence-3)
If it inherits from a single base,
it is as if the scope of the base immediately contains
the scope of the derived class[.](#unqual-2.sentence-4)
Template parameter scopes
that are associated with one scope in the chain of parents
are also considered ([[temp.local]](temp.local "13.8.2Locally declared names"))[.](#unqual-2.sentence-5)
— *end note*]
[3](#unqual-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2005)
[*Unqualified name lookup*](#def:lookup,unqualified_name "6.5.3Unqualified name lookup[basic.lookup.unqual]") from a program point performs an unqualified search in its immediate scope[.](#unqual-3.sentence-1)
[4](#unqual-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2009)
An [*unqualified name*](#def:name,unqualified "6.5.3Unqualified name lookup[basic.lookup.unqual]") is a name
that does not immediately follow a [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]") or
the . or -> in a class member access expression ([[expr.ref]](expr.ref "7.6.1.5Class member access")),
possibly after a template keyword or ~[.](#unqual-4.sentence-1)
Unless otherwise specified,
such a name undergoes unqualified name lookup from the point where it appears[.](#unqual-4.sentence-2)
[5](#unqual-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2017)
An unqualified name that is a component name ([[expr.prim.id.unqual]](expr.prim.id.unqual "7.5.5.2Unqualified names")) of
a [*type-specifier*](dcl.type.general#nt:type-specifier "9.2.9.1General[dcl.type.general]") or [*ptr-operator*](dcl.decl.general#nt:ptr-operator "9.3.1General[dcl.decl.general]") of
a [*conversion-type-id*](class.conv.fct#nt:conversion-type-id "11.4.8.3Conversion functions[class.conv.fct]") is looked up in the same fashion
as the [*conversion-function-id*](class.conv.fct#nt:conversion-function-id "11.4.8.3Conversion functions[class.conv.fct]") in which it appears[.](#unqual-5.sentence-1)
If that lookup finds nothing, it undergoes unqualified name lookup;
in each case, only names
that denote types or templates whose specializations are types are considered[.](#unqual-5.sentence-2)
[*Example [1](#unqual-example-1)*: struct T1 { struct U { int i; }; };struct T2 { };struct U1 {};struct U2 {};
struct B {using T = T1; using U = U1; operator U1 T1::*(); operator U1 T2::*(); operator U2 T1::*(); operator U2 T2::*();};
template<class X, class T>int g() {using U = U2;
X().operator U T::*(); // #1, searches for T in the scope of X first X().operator U decltype(T())::*(); // #2return 0;}int x = g<B, T2>(); // #1 calls B::operator U1 T1::*// #2 calls B::operator U1 T2::* — *end example*]
[6](#unqual-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2053)
In a friend declaration [*declarator*](dcl.decl.general#nt:declarator "9.3.1General[dcl.decl.general]") whose [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1General[dcl.decl.general]") is a [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3Qualified names[expr.prim.id.qual]") whose lookup context ([[basic.lookup.qual]](#qual "6.5.5Qualified name lookup")) is a class or namespace S,
lookup for an unqualified name
that appears after the [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1General[dcl.decl.general]") performs a search in the scope associated with S[.](#unqual-6.sentence-1)
If that lookup finds nothing, it undergoes unqualified name lookup[.](#unqual-6.sentence-2)
[*Example [2](#unqual-example-2)*: using I = int;using D = double;namespace A {inline namespace N {using C = char; }using F = float; void f(I); void f(D); void f(C); void f(F);}struct X0 {using F = float; };struct W {using D = void; struct X : X0 {void g(I); void g(::D); void g(F); };};namespace B {typedef short I, F; class Y {friend void A::f(I); // error: no void A::f(short)friend void A::f(D); // OKfriend void A::f(C); // error: A::N::C not foundfriend void A::f(F); // OKfriend void W::X::g(I); // error: no void X::g(short)friend void W::X::g(D); // OKfriend void W::X::g(F); // OK};} — *end example*]
### [6.5.4](#argdep) Argument-dependent name lookup [[basic.lookup.argdep]](basic.lookup.argdep)
[1](#argdep-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2100)
When the [*postfix-expression*](expr.post.general#nt:postfix-expression "7.6.1.1General[expr.post.general]") in
a function call ([[expr.call]](expr.call "7.6.1.3Function call")) is an [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2Unqualified names[expr.prim.id.unqual]"),
and unqualified lookup ([[basic.lookup.unqual]](#unqual "6.5.3Unqualified name lookup"))
for the name in the [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2Unqualified names[expr.prim.id.unqual]") does not find any
- [(1.1)](#argdep-1.1)
declaration of a class member, or
- [(1.2)](#argdep-1.2)
function declaration inhabiting a block scope, or
- [(1.3)](#argdep-1.3)
declaration not of a function or function template
then lookup for the name also includes the result of[*argument-dependent lookup*](#def:lookup,argument-dependent "6.5.4Argument-dependent name lookup[basic.lookup.argdep]") in a set of associated namespaces
that depends on the types of the arguments
(and for type template template arguments, the namespace of the template argument),
as specified below[.](#argdep-1.sentence-1)
[*Example [1](#argdep-example-1)*: namespace N {struct S { }; void f(S);}void g() { N::S s;
f(s); // OK, calls N::f(f)(s); // error: N::f not considered; parentheses prevent argument-dependent lookup} — *end example*]
[2](#argdep-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2133)
[*Note [1](#argdep-note-1)*:
For purposes of determining
(during parsing) whether an expression is a[*postfix-expression*](expr.post.general#nt:postfix-expression "7.6.1.1General[expr.post.general]") for a function call, the usual name lookup
rules apply[.](#argdep-2.sentence-1)
In some cases
a name followed by < is treated as a [*template-name*](temp.names#nt:template-name "13.3Names of template specializations[temp.names]") even though name lookup did not find a [*template-name*](temp.names#nt:template-name "13.3Names of template specializations[temp.names]") (see [[temp.names]](temp.names "13.3Names of template specializations"))[.](#argdep-2.sentence-2)
For example,int h;void g();namespace N {struct A {}; template <class T> int f(T); template <class T> int g(T); template <class T> int h(T);}int x = f<N::A>(N::A()); // OK, lookup of f finds nothing, f treated as template nameint y = g<N::A>(N::A()); // OK, lookup of g finds a function, g treated as template nameint z = h<N::A>(N::A()); // error: h< does not begin a [*template-id*](temp.names#nt:template-id "13.3Names of template specializations[temp.names]")
The rules have no effect on the syntactic interpretation of an expression[.](#argdep-2.sentence-4)
For example,typedef int f;namespace N {struct A {friend void f(A &); operator int(); void g(A a) {int i = f(a); // f is the typedef, not the friend function: equivalent to int(a)}};}
Because the expression is not a function call,
argument-dependent name lookup does not apply and
the friend function f is not found[.](#argdep-2.sentence-6)
— *end note*]
[3](#argdep-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2178)
For each argument type T in the function call,
there is a set of zero or more [*associated entities*](#def:entity,associated "6.5.4Argument-dependent name lookup[basic.lookup.argdep]") to be considered[.](#argdep-3.sentence-1)
The set of entities is determined entirely by
the types of the function arguments
(and any type template template arguments)[.](#argdep-3.sentence-2)
Any [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4The typedef specifier[dcl.typedef]")*s* and [*using-declaration*](namespace.udecl#nt:using-declaration "9.10The using declaration[namespace.udecl]")*s* used to specify the types
do not contribute to this set[.](#argdep-3.sentence-3)
The set of entities
is determined in the following way:
- [(3.1)](#argdep-3.1)
If T is std::meta::info ([[meta.syn]](meta.syn "21.4.1Header <meta> synopsis")),
its associated set of entities is the singleton containing
the enumeration type std::meta::operators ([[meta.reflection.operators]](meta.reflection.operators "21.4.5Operator representations"))[.](#argdep-3.1.sentence-1)
[*Note [2](#argdep-note-2)*:
The std::meta::info type is a type alias,
so an explicit rule is needed to associate calls
whose arguments are reflections with the namespace std::meta[.](#argdep-3.1.sentence-2)
— *end note*]
- [(3.2)](#argdep-3.2)
If T is any other fundamental type, its associated set of
entities is empty[.](#argdep-3.2.sentence-1)
- [(3.3)](#argdep-3.3)
If T is a class type (including unions),
its associated entities are:
the class itself;
the class of which it is a member, if any;
and, if it is a complete type, its direct and indirect base classes[.](#argdep-3.3.sentence-1)
Furthermore, if T is a class template specialization,
its associated entities also include:
the entities
associated with the types of the template arguments
provided for template type parameters;
the templates used as type template template arguments; and
the classes of which any member templates used as type template template
arguments are members[.](#argdep-3.3.sentence-2)
[*Note [3](#argdep-note-3)*:
Constant template arguments,
variable template template arguments, and
concept template arguments
do not
contribute to the set of associated entities[.](#argdep-3.3.sentence-3)
— *end note*]
- [(3.4)](#argdep-3.4)
If T is an enumeration type,
its associated entities are T and, if it is a class member, the member's class[.](#argdep-3.4.sentence-1)
- [(3.5)](#argdep-3.5)
If T is a pointer to U or an array of U,
its associated entities are those associated with U[.](#argdep-3.5.sentence-1)
- [(3.6)](#argdep-3.6)
If T is a function type, its associated
entities are those associated with the function parameter types and those
associated with the return type[.](#argdep-3.6.sentence-1)
- [(3.7)](#argdep-3.7)
If T is a pointer to a member function of a classX, its associated entities are those associated
with the function parameter types and return type, together with those
associated with X[.](#argdep-3.7.sentence-1)
- [(3.8)](#argdep-3.8)
If T is a pointer to a data member of class X, its
associated entities are those associated with the member
type together with those associated with X[.](#argdep-3.8.sentence-1)
In addition, if the argument is an overload set or the address of such a set,
its associated entities
are the union of those associated with each of the
members of the set, i.e., the entities associated with its
parameter types and return type[.](#argdep-3.sentence-5)
Additionally, if the aforementioned overload set is named with
a [*template-id*](temp.names#nt:template-id "13.3Names of template specializations[temp.names]"), its associated entities also include
its template template arguments and
those associated with its type template arguments[.](#argdep-3.sentence-6)
[4](#argdep-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2254)
The [*associated namespaces*](#def:associated_namespaces) for a call are
the innermost enclosing non-inline namespaces for its associated entities
as well as every element of the inline namespace set ([[namespace.def]](namespace.def "9.9.2Namespace definition"))
of those namespaces[.](#argdep-4.sentence-1)
Argument-dependent lookup finds
all declarations of functions and function templates that
- [(4.1)](#argdep-4.1)
are found by a search of any associated namespace, or
- [(4.2)](#argdep-4.2)
are declared as a friend ([[class.friend]](class.friend "11.8.4Friends")) of any class
with a reachable definition in the set of associated entities, or
- [(4.3)](#argdep-4.3)
are exported,
are attached to a named module M ([[module.interface]](module.interface "10.2Export declaration")),
do not appear in the translation unit containing the point of the lookup, and
have the same innermost enclosing non-inline namespace scope as
a declaration of an associated entity attached to M ([[basic.link]](basic.link "6.7Program and linkage"))[.](#argdep-4.sentence-2)
If the lookup is for a dependent name ([[temp.dep]](temp.dep "13.8.3Dependent names"), [[temp.dep.candidate]](temp.dep.candidate "13.8.4.2Candidate functions")),
the above lookup is also performed
from each point in the instantiation context ([[module.context]](module.context "10.6Instantiation context")) of the lookup,
additionally ignoring any declaration that
appears in another translation unit,
is attached to the global module, and
is either discarded ([[module.global.frag]](module.global.frag "10.4Global module fragment")) or has internal linkage[.](#argdep-4.sentence-3)
[5](#argdep-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2282)
[*Example [2](#argdep-example-2)*:
Translation unit #1:export module M;namespace R {export struct X {}; export void f(X);}namespace S {export void f(R::X, R::X);}
Translation unit #2:export module N;import M;export R::X make();namespace R { static int g(X); }export template<typename T, typename U> void apply(T t, U u) { f(t, u);
g(t);}
Translation unit #3:module Q;import N;namespace S {struct Z { template<typename T> operator T(); };}void test() {auto x = make(); // OK, decltype(x) is R::X in module M R::f(x); // error: R and R::f are not visible here f(x); // OK, calls R::f from interface of M f(x, S::Z()); // error: S::f in module M not considered// even though S is an associated namespace apply(x, S::Z()); // error: S::f is visible in instantiation context, but// R::g has internal linkage and cannot be used outside TU #2} — *end example*]
[6](#argdep-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2324)
[*Note [4](#argdep-note-4)*:
The associated namespace can include namespaces
already considered by ordinary unqualified lookup[.](#argdep-6.sentence-1)
— *end note*]
[*Example [3](#argdep-example-3)*: namespace NS {class T { }; void f(T); void g(T, int);} NS::T parm;void g(NS::T, float);int main() { f(parm); // OK, calls NS::fextern void g(NS::T, float);
g(parm, 1); // OK, calls g(NS::T, float)} — *end example*]
### [6.5.5](#qual) Qualified name lookup [[basic.lookup.qual]](basic.lookup.qual)
#### [6.5.5.1](#qual.general) General [[basic.lookup.qual.general]](basic.lookup.qual.general)
[1](#qual.general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2350)
Lookup of an [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") followed by a :: scope resolution operator
considers only
namespaces, types, and templates whose specializations are types[.](#qual.general-1.sentence-1)
If a
name,[*template-id*](temp.names#nt:template-id "13.3Names of template specializations[temp.names]"),[*splice-scope-specifier*](expr.prim.id.qual#nt:splice-scope-specifier "7.5.5.3Qualified names[expr.prim.id.qual]"), or[*computed-type-specifier*](dcl.type.simple#nt:computed-type-specifier "9.2.9.3Simple type specifiers[dcl.type.simple]") is followed by a ::,
it shall either be
a dependent [*splice-scope-specifier*](expr.prim.id.qual#nt:splice-scope-specifier "7.5.5.3Qualified names[expr.prim.id.qual]") ([[temp.dep.splice]](temp.dep.splice "13.8.3.5Dependent splice specifiers")) or
it shall designate a namespace, class, enumeration, or dependent type,
and the :: is never interpreted as
a complete [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]")[.](#qual.general-1.sentence-2)
[*Example [1](#qual.general-example-1)*: class A {public:static int n;};int main() {int A;
A::n = 42; // OK A b; // error: A does not name a type}template<int> struct B : A {};namespace N {template<int> void B(); int f() {return B<0>::n; // error: N::B<0> is not a type}} — *end example*]
[2](#qual.general-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2393)
A member-qualified name is
the (unique) component name ([[expr.prim.id.unqual]](expr.prim.id.unqual "7.5.5.2Unqualified names")), if any, of
- [(2.1)](#qual.general-2.1)
an [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2Unqualified names[expr.prim.id.unqual]") or
- [(2.2)](#qual.general-2.2)
a [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]") of the form[*type-name*](dcl.type.simple#nt:type-name "9.2.9.3Simple type specifiers[dcl.type.simple]") :: or [*namespace-name*](namespace.def.general#nt:namespace-name "9.9.2.1General[namespace.def.general]") ::
in the [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1General[expr.prim.id.general]") of a class member access expression ([[expr.ref]](expr.ref "7.6.1.5Class member access"))[.](#qual.general-2.sentence-1)
A [*qualified name*](#def:name,qualified "6.5.5.1General[basic.lookup.qual.general]") is
- [(2.3)](#qual.general-2.3)
a member-qualified name or
- [(2.4)](#qual.general-2.4)
the terminal name of
* [(2.4.1)](#qual.general-2.4.1)
a [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3Qualified names[expr.prim.id.qual]"),
* [(2.4.2)](#qual.general-2.4.2)
a [*using-declarator*](namespace.udecl#nt:using-declarator "9.10The using declaration[namespace.udecl]"),
* [(2.4.3)](#qual.general-2.4.3)
a [*typename-specifier*](temp.res.general#nt:typename-specifier "13.8.1General[temp.res.general]"),
* [(2.4.4)](#qual.general-2.4.4)
a [*qualified-namespace-specifier*](namespace.alias#nt:qualified-namespace-specifier "9.9.3Namespace alias[namespace.alias]"), or
* [(2.4.5)](#qual.general-2.4.5)
a [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]"),[*reflection-name*](expr.reflect#nt:reflection-name "7.6.2.10The reflection operator[expr.reflect]"),[*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5Elaborated type specifiers[dcl.type.elab]"), or[*class-or-decltype*](class.derived.general#nt:class-or-decltype "11.7.1General[class.derived.general]") that has a [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]") ([[expr.prim.id.qual]](expr.prim.id.qual "7.5.5.3Qualified names"))[.](#qual.general-2.sentence-2)
The [*lookup context*](#def:lookup_context "6.5.5.1General[basic.lookup.qual.general]") of a member-qualified name is
the type of its associated object expression
(considered dependent if the object expression is type-dependent)[.](#qual.general-2.sentence-3)
The lookup context of any other qualified name is
the type, template, or namespace
nominated by the preceding [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]")[.](#qual.general-2.sentence-4)
[*Note [1](#qual.general-note-1)*:
When parsing a class member access,
the name following the -> or . is
a qualified name even though it is not yet known of which kind[.](#qual.general-2.sentence-5)
— *end note*]
[*Example [2](#qual.general-example-2)*:
In N::C::m.Base::f()Base is a member-qualified name;
the other qualified names are C, m, and f[.](#qual.general-2.sentence-6)
— *end example*]
[3](#qual.general-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2440)
[*Qualified name lookup*](#def:lookup,qualified_name "6.5.5.1General[basic.lookup.qual.general]") in a class, namespace, or enumeration performs
a search of the scope associated with it ([[class.member.lookup]](#class.member.lookup "6.5.2Member name lookup"))
except as specified below[.](#qual.general-3.sentence-1)
Unless otherwise specified,
a qualified name undergoes qualified name lookup in its lookup context
from the point where it appears
unless the lookup context either
is dependent and is not the current instantiation ([[temp.dep.type]](temp.dep.type "13.8.3.2Dependent types")) or
is not a class or class template[.](#qual.general-3.sentence-2)
If nothing is found by qualified lookup for a member-qualified name
that is the terminal name ([[expr.prim.id.unqual]](expr.prim.id.unqual "7.5.5.2Unqualified names")) of
a [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]") and
is not dependent, it undergoes unqualified lookup[.](#qual.general-3.sentence-3)
[*Note [2](#qual.general-note-2)*:
During lookup for a template specialization, no names are dependent[.](#qual.general-3.sentence-4)
— *end note*]
[*Example [3](#qual.general-example-3)*: int f();struct A {int B, C; template<int> using D = void; using T = void; void f();};using B = A;template<int> using C = A;template<int> using D = A;template<int> using X = A;
template<class T>void g(T *p) { // as instantiated for g<A>: p->X<0>::f(); // error: A::X not found in ((p->X) < 0) > ::f() p->template X<0>::f(); // OK, ::X found in definition context p->B::f(); // OK, non-type A::B ignored p->template C<0>::f(); // error: A::C is not a template p->template D<0>::f(); // error: A::D<0> is not a class type p->T::f(); // error: A::T is not a class type}template void g(A*); — *end example*]
[4](#qual.general-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2485)
If a qualified name Q follows a ~:
- [(4.1)](#qual.general-4.1)
If Q is a member-qualified name,
it undergoes unqualified lookup as well as qualified lookup[.](#qual.general-4.1.sentence-1)
- [(4.2)](#qual.general-4.2)
Otherwise, its [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]") N shall nominate a type[.](#qual.general-4.2.sentence-1)
If N has another [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]") S,Q is looked up as if its lookup context were that nominated by S[.](#qual.general-4.2.sentence-2)
- [(4.3)](#qual.general-4.3)
Otherwise, if the terminal name of N is a member-qualified name M,Q is looked up as if ~Q appeared in place of M (as above)[.](#qual.general-4.3.sentence-1)
- [(4.4)](#qual.general-4.4)
Otherwise, Q undergoes unqualified lookup[.](#qual.general-4.4.sentence-1)
- [(4.5)](#qual.general-4.5)
Each lookup for Q considers only
types (if Q is not followed by a <) and
templates whose specializations are types[.](#qual.general-4.5.sentence-1)
If it finds nothing or is ambiguous, it is discarded[.](#qual.general-4.5.sentence-2)
- [(4.6)](#qual.general-4.6)
The [*type-name*](dcl.type.simple#nt:type-name "9.2.9.3Simple type specifiers[dcl.type.simple]") that is or contains Q shall refer to its (original) lookup context (ignoring cv-qualification) under
the interpretation established by at least one (successful) lookup performed[.](#qual.general-4.6.sentence-1)
[*Example [4](#qual.general-example-4)*: struct C {typedef int I;};typedef int I1, I2;extern int* p;extern int* q;void f() { p->C::I::~I(); // I is looked up in the scope of C q->I1::~I2(); // I2 is found by unqualified lookup}struct A {~A();};typedef A AB;int main() { AB* p;
p->AB::~AB(); // explicitly calls the destructor for A} — *end example*]
#### [6.5.5.2](#class.qual) Class members [[class.qual]](class.qual)
[1](#class.qual-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2537)
In a lookup for a qualified name N whose lookup context is a class C in which function names are not ignored,[18](#footnote-18 "Lookups in which function names are ignored include names appearing in a nested-name-specifier, an elaborated-type-specifier, or a base-specifier.")
- [(1.1)](#class.qual-1.1)
if the search finds the injected-class-name of C ([[class.pre]](class.pre "11.1Preamble")), or
- [(1.2)](#class.qual-1.2)
if N is dependent and
is the terminal name of a [*using-declarator*](namespace.udecl#nt:using-declarator "9.10The using declaration[namespace.udecl]") ([[namespace.udecl]](namespace.udecl "9.10The using declaration"))
that names a constructor,
N is instead considered to name the constructor of class C[.](#class.qual-1.sentence-1)
Such a constructor name shall be used only
in the [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1General[dcl.decl.general]") of a (friend) declaration of a constructor or
in a [*using-declaration*](namespace.udecl#nt:using-declaration "9.10The using declaration[namespace.udecl]")[.](#class.qual-1.sentence-2)
[*Example [1](#class.qual-example-1)*: struct A { A(); };struct B: public A { B(); };
A::A() { } B::B() { } B::A ba; // object of type A A::A a; // error: A::A is not a type namestruct A::A a2; // object of type A — *end example*]
[18)](#footnote-18)[18)](#footnoteref-18)
Lookups in which
function names are ignored include names appearing in a[*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]"), an[*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5Elaborated type specifiers[dcl.type.elab]"), or a [*base-specifier*](class.derived.general#nt:base-specifier "11.7.1General[class.derived.general]")[.](#footnote-18.sentence-1)
#### [6.5.5.3](#namespace.qual) Namespace members [[namespace.qual]](namespace.qual)
[1](#namespace.qual-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2574)
Qualified name lookup in a namespace N additionally searches
every element of the inline namespace set of N ([[namespace.def]](namespace.def "9.9.2Namespace definition"))[.](#namespace.qual-1.sentence-1)
If nothing is found,
the results of the lookup are the results of qualified name lookup
in each namespace nominated by a [*using-directive*](namespace.udir#nt:using-directive "9.9.4Using namespace directive[namespace.udir]") that precedes the point of the lookup and
inhabits N or an element of N's inline namespace set[.](#namespace.qual-1.sentence-2)
[*Note [1](#namespace.qual-note-1)*:
If a [*using-directive*](namespace.udir#nt:using-directive "9.9.4Using namespace directive[namespace.udir]") refers to a namespace
that has already been considered, it does not affect the result[.](#namespace.qual-1.sentence-3)
— *end note*]
[*Example [1](#namespace.qual-example-1)*: int x;namespace Y {void f(float); void h(int);}namespace Z {void h(double);}namespace A {using namespace Y; void f(int); void g(int); int i;}namespace B {using namespace Z; void f(char); int i;}namespace AB {using namespace A; using namespace B; void g();}void h(){ AB::g(); // g is declared directly in AB, therefore S is { AB::g() } and AB::g() is chosen AB::f(1); // f is not declared directly in AB so the rules are applied recursively to A and B;// namespace Y is not searched and Y::f(float) is not considered;// S is { A::f(int), B::f(char) } and overload resolution chooses A::f(int) AB::f('c'); // as above but resolution chooses B::f(char) AB::x++; // x is not declared directly in AB, and is not declared in A or B, so the rules// are applied recursively to Y and Z, S is { } so the program is ill-formed AB::i++; // i is not declared directly in AB so the rules are applied recursively to A and B,// S is { A::i, B::i } so the use is ambiguous and the program is ill-formed AB::h(16.8); // h is not declared directly in AB and not declared directly in A or B so the rules// are applied recursively to Y and Z, S is { Y::h(int), Z::h(double) } and// overload resolution chooses Z::h(double)} — *end example*]
[2](#namespace.qual-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2640)
[*Note [2](#namespace.qual-note-2)*:
The same declaration found more than once is not an ambiguity (because
it is still a unique declaration)[.](#namespace.qual-2.sentence-1)
[*Example [2](#namespace.qual-example-2)*: namespace A {int a;}namespace B {using namespace A;}namespace C {using namespace A;}namespace BC {using namespace B; using namespace C;}void f(){ BC::a++; // OK, S is { A::a, A::a }}namespace D {using A::a;}namespace BD {using namespace B; using namespace D;}void g(){ BD::a++; // OK, S is { A::a, A::a }} — *end example*]
— *end note*]
[3](#namespace.qual-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2685)
[*Example [3](#namespace.qual-example-3)*:
Because each referenced namespace is searched at most once, the
following is well-defined:namespace B {int b;}namespace A {using namespace B; int a;}namespace B {using namespace A;}void f(){ A::a++; // OK, a declared directly in A, S is { A::a } B::a++; // OK, both A and B searched (once), S is { A::a } A::b++; // OK, both A and B searched (once), S is { B::b } B::b++; // OK, b declared directly in B, S is { B::b }}
— *end example*]
[4](#namespace.qual-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2713)
[*Note [3](#namespace.qual-note-3)*:
Class and enumeration declarations are not discarded
because of other declarations found in other searches[.](#namespace.qual-4.sentence-1)
— *end note*]
[*Example [4](#namespace.qual-example-4)*: namespace A {struct x { }; int x; int y;}namespace B {struct y { };}namespace C {using namespace A; using namespace B; int i = C::x; // OK, A::x (of type int)int j = C::y; // ambiguous, A::y or B::y} — *end example*]
### [6.5.6](#elab) Elaborated type specifiers [[basic.lookup.elab]](basic.lookup.elab)
[1](#elab-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2745)
If the [*class-key*](class.pre#nt:class-key "11.1Preamble[class.pre]") or enum keyword
in an [*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5Elaborated type specifiers[dcl.type.elab]") is followed by an [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") that is not followed by ::,
lookup for the [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") is type-only ([[basic.lookup.general]](#general "6.5.1General"))[.](#elab-1.sentence-1)
[*Note [1](#elab-note-1)*:
In general, the recognition of an [*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5Elaborated type specifiers[dcl.type.elab]") depends on the following tokens[.](#elab-1.sentence-2)
If the [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") is followed by ::,
see [[basic.lookup.qual]](#qual "6.5.5Qualified name lookup")[.](#elab-1.sentence-3)
— *end note*]
[2](#elab-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2758)
If the terminal name of the [*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5Elaborated type specifiers[dcl.type.elab]") is a qualified name,
lookup for it is type-only[.](#elab-2.sentence-1)
If the name lookup does not find a previously declared [*type-name*](dcl.type.simple#nt:type-name "9.2.9.3Simple type specifiers[dcl.type.simple]"),
the [*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5Elaborated type specifiers[dcl.type.elab]") is ill-formed[.](#elab-2.sentence-2)
[3](#elab-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2765)
[*Example [1](#elab-example-1)*: struct Node {struct Node* Next; // OK, refers to injected-class-name Nodestruct Data* Data; // OK, declares type Data at global scope and member Data};
struct Data {struct Node* Node; // OK, refers to Node at global scopefriend struct ::Glob; // error: Glob is not declared, cannot introduce a qualified type ([[dcl.type.elab]](dcl.type.elab "9.2.9.5Elaborated type specifiers"))friend struct Glob; // OK, refers to (as yet) undeclared Glob at global scope./* ... */};
struct Base {struct Data; // OK, declares nested Datastruct ::Data* thatData; // OK, refers to ::Datastruct Base::Data* thisData; // OK, refers to nested Datafriend class ::Data; // OK, global Data is a friendfriend class Data; // OK, nested Data is a friendstruct Data { /* ... */ }; // Defines nested Data};
struct Data; // OK, redeclares Data at global scopestruct ::Data; // error: cannot introduce a qualified type ([[dcl.type.elab]](dcl.type.elab "9.2.9.5Elaborated type specifiers"))struct Base::Data; // error: cannot introduce a qualified type ([[dcl.type.elab]](dcl.type.elab "9.2.9.5Elaborated type specifiers"))struct Base::Datum; // error: Datum undefinedstruct Base::Data* pBase; // OK, refers to nested Data — *end example*]
### [6.5.7](#udir) Using-directives and namespace aliases [[basic.lookup.udir]](basic.lookup.udir)
[1](#udir-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2800)
In a [*using-directive*](namespace.udir#nt:using-directive "9.9.4Using namespace directive[namespace.udir]") or [*namespace-alias-definition*](namespace.alias#nt:namespace-alias-definition "9.9.3Namespace alias[namespace.alias]"),
during the lookup for a [*namespace-name*](namespace.def.general#nt:namespace-name "9.9.2.1General[namespace.def.general]") or for a name in a[*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]") only namespace names are considered[.](#udir-1.sentence-1)

View File

@@ -0,0 +1,220 @@
[basic.lookup.argdep]
# 6 Basics [[basic]](./#basic)
## 6.5 Name lookup [[basic.lookup]](basic.lookup#argdep)
### 6.5.4 Argument-dependent name lookup [basic.lookup.argdep]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2100)
When the [*postfix-expression*](expr.post.general#nt:postfix-expression "7.6.1.1General[expr.post.general]") in
a function call ([[expr.call]](expr.call "7.6.1.3Function call")) is an [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2Unqualified names[expr.prim.id.unqual]"),
and unqualified lookup ([[basic.lookup.unqual]](basic.lookup.unqual "6.5.3Unqualified name lookup"))
for the name in the [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2Unqualified names[expr.prim.id.unqual]") does not find any
- [(1.1)](#1.1)
declaration of a class member, or
- [(1.2)](#1.2)
function declaration inhabiting a block scope, or
- [(1.3)](#1.3)
declaration not of a function or function template
then lookup for the name also includes the result of[*argument-dependent lookup*](#def:lookup,argument-dependent "6.5.4Argument-dependent name lookup[basic.lookup.argdep]") in a set of associated namespaces
that depends on the types of the arguments
(and for type template template arguments, the namespace of the template argument),
as specified below[.](#1.sentence-1)
[*Example [1](#example-1)*: namespace N {struct S { }; void f(S);}void g() { N::S s;
f(s); // OK, calls N::f(f)(s); // error: N::f not considered; parentheses prevent argument-dependent lookup} — *end example*]
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2133)
[*Note [1](#note-1)*:
For purposes of determining
(during parsing) whether an expression is a[*postfix-expression*](expr.post.general#nt:postfix-expression "7.6.1.1General[expr.post.general]") for a function call, the usual name lookup
rules apply[.](#2.sentence-1)
In some cases
a name followed by < is treated as a [*template-name*](temp.names#nt:template-name "13.3Names of template specializations[temp.names]") even though name lookup did not find a [*template-name*](temp.names#nt:template-name "13.3Names of template specializations[temp.names]") (see [[temp.names]](temp.names "13.3Names of template specializations"))[.](#2.sentence-2)
For example,int h;void g();namespace N {struct A {}; template <class T> int f(T); template <class T> int g(T); template <class T> int h(T);}int x = f<N::A>(N::A()); // OK, lookup of f finds nothing, f treated as template nameint y = g<N::A>(N::A()); // OK, lookup of g finds a function, g treated as template nameint z = h<N::A>(N::A()); // error: h< does not begin a [*template-id*](temp.names#nt:template-id "13.3Names of template specializations[temp.names]")
The rules have no effect on the syntactic interpretation of an expression[.](#2.sentence-4)
For example,typedef int f;namespace N {struct A {friend void f(A &); operator int(); void g(A a) {int i = f(a); // f is the typedef, not the friend function: equivalent to int(a)}};}
Because the expression is not a function call,
argument-dependent name lookup does not apply and
the friend function f is not found[.](#2.sentence-6)
— *end note*]
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2178)
For each argument type T in the function call,
there is a set of zero or more [*associated entities*](#def:entity,associated "6.5.4Argument-dependent name lookup[basic.lookup.argdep]") to be considered[.](#3.sentence-1)
The set of entities is determined entirely by
the types of the function arguments
(and any type template template arguments)[.](#3.sentence-2)
Any [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4The typedef specifier[dcl.typedef]")*s* and [*using-declaration*](namespace.udecl#nt:using-declaration "9.10The using declaration[namespace.udecl]")*s* used to specify the types
do not contribute to this set[.](#3.sentence-3)
The set of entities
is determined in the following way:
- [(3.1)](#3.1)
If T is std::meta::info ([[meta.syn]](meta.syn "21.4.1Header <meta> synopsis")),
its associated set of entities is the singleton containing
the enumeration type std::meta::operators ([[meta.reflection.operators]](meta.reflection.operators "21.4.5Operator representations"))[.](#3.1.sentence-1)
[*Note [2](#note-2)*:
The std::meta::info type is a type alias,
so an explicit rule is needed to associate calls
whose arguments are reflections with the namespace std::meta[.](#3.1.sentence-2)
— *end note*]
- [(3.2)](#3.2)
If T is any other fundamental type, its associated set of
entities is empty[.](#3.2.sentence-1)
- [(3.3)](#3.3)
If T is a class type (including unions),
its associated entities are:
the class itself;
the class of which it is a member, if any;
and, if it is a complete type, its direct and indirect base classes[.](#3.3.sentence-1)
Furthermore, if T is a class template specialization,
its associated entities also include:
the entities
associated with the types of the template arguments
provided for template type parameters;
the templates used as type template template arguments; and
the classes of which any member templates used as type template template
arguments are members[.](#3.3.sentence-2)
[*Note [3](#note-3)*:
Constant template arguments,
variable template template arguments, and
concept template arguments
do not
contribute to the set of associated entities[.](#3.3.sentence-3)
— *end note*]
- [(3.4)](#3.4)
If T is an enumeration type,
its associated entities are T and, if it is a class member, the member's class[.](#3.4.sentence-1)
- [(3.5)](#3.5)
If T is a pointer to U or an array of U,
its associated entities are those associated with U[.](#3.5.sentence-1)
- [(3.6)](#3.6)
If T is a function type, its associated
entities are those associated with the function parameter types and those
associated with the return type[.](#3.6.sentence-1)
- [(3.7)](#3.7)
If T is a pointer to a member function of a classX, its associated entities are those associated
with the function parameter types and return type, together with those
associated with X[.](#3.7.sentence-1)
- [(3.8)](#3.8)
If T is a pointer to a data member of class X, its
associated entities are those associated with the member
type together with those associated with X[.](#3.8.sentence-1)
In addition, if the argument is an overload set or the address of such a set,
its associated entities
are the union of those associated with each of the
members of the set, i.e., the entities associated with its
parameter types and return type[.](#3.sentence-5)
Additionally, if the aforementioned overload set is named with
a [*template-id*](temp.names#nt:template-id "13.3Names of template specializations[temp.names]"), its associated entities also include
its template template arguments and
those associated with its type template arguments[.](#3.sentence-6)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2254)
The [*associated namespaces*](#def:associated_namespaces) for a call are
the innermost enclosing non-inline namespaces for its associated entities
as well as every element of the inline namespace set ([[namespace.def]](namespace.def "9.9.2Namespace definition"))
of those namespaces[.](#4.sentence-1)
Argument-dependent lookup finds
all declarations of functions and function templates that
- [(4.1)](#4.1)
are found by a search of any associated namespace, or
- [(4.2)](#4.2)
are declared as a friend ([[class.friend]](class.friend "11.8.4Friends")) of any class
with a reachable definition in the set of associated entities, or
- [(4.3)](#4.3)
are exported,
are attached to a named module M ([[module.interface]](module.interface "10.2Export declaration")),
do not appear in the translation unit containing the point of the lookup, and
have the same innermost enclosing non-inline namespace scope as
a declaration of an associated entity attached to M ([[basic.link]](basic.link "6.7Program and linkage"))[.](#4.sentence-2)
If the lookup is for a dependent name ([[temp.dep]](temp.dep "13.8.3Dependent names"), [[temp.dep.candidate]](temp.dep.candidate "13.8.4.2Candidate functions")),
the above lookup is also performed
from each point in the instantiation context ([[module.context]](module.context "10.6Instantiation context")) of the lookup,
additionally ignoring any declaration that
appears in another translation unit,
is attached to the global module, and
is either discarded ([[module.global.frag]](module.global.frag "10.4Global module fragment")) or has internal linkage[.](#4.sentence-3)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2282)
[*Example [2](#example-2)*:
Translation unit #1:export module M;namespace R {export struct X {}; export void f(X);}namespace S {export void f(R::X, R::X);}
Translation unit #2:export module N;import M;export R::X make();namespace R { static int g(X); }export template<typename T, typename U> void apply(T t, U u) { f(t, u);
g(t);}
Translation unit #3:module Q;import N;namespace S {struct Z { template<typename T> operator T(); };}void test() {auto x = make(); // OK, decltype(x) is R::X in module M R::f(x); // error: R and R::f are not visible here f(x); // OK, calls R::f from interface of M f(x, S::Z()); // error: S::f in module M not considered// even though S is an associated namespace apply(x, S::Z()); // error: S::f is visible in instantiation context, but// R::g has internal linkage and cannot be used outside TU #2} — *end example*]
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2324)
[*Note [4](#note-4)*:
The associated namespace can include namespaces
already considered by ordinary unqualified lookup[.](#6.sentence-1)
— *end note*]
[*Example [3](#example-3)*: namespace NS {class T { }; void f(T); void g(T, int);} NS::T parm;void g(NS::T, float);int main() { f(parm); // OK, calls NS::fextern void g(NS::T, float);
g(parm, 1); // OK, calls g(NS::T, float)} — *end example*]

View File

@@ -0,0 +1,46 @@
[basic.lookup.elab]
# 6 Basics [[basic]](./#basic)
## 6.5 Name lookup [[basic.lookup]](basic.lookup#elab)
### 6.5.6 Elaborated type specifiers [basic.lookup.elab]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2745)
If the [*class-key*](class.pre#nt:class-key "11.1Preamble[class.pre]") or enum keyword
in an [*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5Elaborated type specifiers[dcl.type.elab]") is followed by an [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") that is not followed by ::,
lookup for the [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") is type-only ([[basic.lookup.general]](basic.lookup.general "6.5.1General"))[.](#1.sentence-1)
[*Note [1](#note-1)*:
In general, the recognition of an [*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5Elaborated type specifiers[dcl.type.elab]") depends on the following tokens[.](#1.sentence-2)
If the [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") is followed by ::,
see [[basic.lookup.qual]](basic.lookup.qual "6.5.5Qualified name lookup")[.](#1.sentence-3)
— *end note*]
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2758)
If the terminal name of the [*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5Elaborated type specifiers[dcl.type.elab]") is a qualified name,
lookup for it is type-only[.](#2.sentence-1)
If the name lookup does not find a previously declared [*type-name*](dcl.type.simple#nt:type-name "9.2.9.3Simple type specifiers[dcl.type.simple]"),
the [*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5Elaborated type specifiers[dcl.type.elab]") is ill-formed[.](#2.sentence-2)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2765)
[*Example [1](#example-1)*: struct Node {struct Node* Next; // OK, refers to injected-class-name Nodestruct Data* Data; // OK, declares type Data at global scope and member Data};
struct Data {struct Node* Node; // OK, refers to Node at global scopefriend struct ::Glob; // error: Glob is not declared, cannot introduce a qualified type ([[dcl.type.elab]](dcl.type.elab "9.2.9.5Elaborated type specifiers"))friend struct Glob; // OK, refers to (as yet) undeclared Glob at global scope./* ... */};
struct Base {struct Data; // OK, declares nested Datastruct ::Data* thatData; // OK, refers to ::Datastruct Base::Data* thisData; // OK, refers to nested Datafriend class ::Data; // OK, global Data is a friendfriend class Data; // OK, nested Data is a friendstruct Data { /* ... */ }; // Defines nested Data};
struct Data; // OK, redeclares Data at global scopestruct ::Data; // error: cannot introduce a qualified type ([[dcl.type.elab]](dcl.type.elab "9.2.9.5Elaborated type specifiers"))struct Base::Data; // error: cannot introduce a qualified type ([[dcl.type.elab]](dcl.type.elab "9.2.9.5Elaborated type specifiers"))struct Base::Datum; // error: Datum undefinedstruct Base::Data* pBase; // OK, refers to nested Data — *end example*]

View File

@@ -0,0 +1,126 @@
[basic.lookup.general]
# 6 Basics [[basic]](./#basic)
## 6.5 Name lookup [[basic.lookup]](basic.lookup#general)
### 6.5.1 General [basic.lookup.general]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1624)
[*Name lookup*](#def:lookup,name "6.5.1General[basic.lookup.general]") associates the use of a name
with a set of declarations ([[basic.def]](basic.def "6.2Declarations and definitions")) of that name[.](#1.sentence-1)
The name lookup rules apply uniformly to all names (including[*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4The typedef specifier[dcl.typedef]")*s* ([[dcl.typedef]](dcl.typedef "9.2.4The typedef specifier")),[*namespace-name*](namespace.def.general#nt:namespace-name "9.9.2.1General[namespace.def.general]")*s* ([[basic.namespace]](basic.namespace "9.9Namespaces")), and[*class-name*](class.pre#nt:class-name "11.1Preamble[class.pre]")*s* ([[class.name]](class.name "11.3Class names"))) wherever the grammar allows
such names in the context discussed by a particular rule[.](#1.sentence-2)
Unless otherwise specified,
the program is ill-formed if no declarations are found[.](#1.sentence-3)
If the declarations found by name lookup
all denote functions or function templates,
the declarations are said to form an [*overload set*](#def:overload_set "6.5.1General[basic.lookup.general]")[.](#1.sentence-4)
Otherwise,
if the declarations found by name lookup do not all denote the same entity,they are [*ambiguous*](#def:ambiguous "6.5.1General[basic.lookup.general]") and the program is ill-formed[.](#1.sentence-5)
Overload resolution ([[over.match]](over.match "12.2Overload resolution"), [[over.over]](over.over "12.3Address of an overload set"))
takes place after name lookup has succeeded[.](#1.sentence-6)
The access rules ([[class.access]](class.access "11.8Member access control"))
are considered only once name lookup and
function overload resolution (if applicable) have succeeded[.](#1.sentence-7)
Only after
name lookup, function overload resolution (if applicable) and access
checking have succeeded
are the semantic properties introduced by the declarations
used in further processing[.](#1.sentence-8)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1650)
A program point P is said to follow
any declaration in the same translation unit
whose locus ([[basic.scope.pdecl]](basic.scope.pdecl "6.4.2Point of declaration")) is before P[.](#2.sentence-1)
[*Note [1](#note-1)*:
The declaration might appear in a scope that does not contain P[.](#2.sentence-2)
— *end note*]
A declaration X [*precedes*](#def:declaration,precede "6.5.1General[basic.lookup.general]") a program point P in a translation unit L if P follows X, X inhabits a class scope and is reachable from P, or
else X appears in a translation unit D and
- [(2.1)](#2.1)
P follows
a [*module-import-declaration*](module.import#nt:module-import-declaration "10.3Import declaration[module.import]") or [*module-declaration*](module.unit#nt:module-declaration "10.1Module units and purviews[module.unit]") that imports D (directly or indirectly), and
- [(2.2)](#2.2)
X appears after the [*module-declaration*](module.unit#nt:module-declaration "10.1Module units and purviews[module.unit]") in D (if any) and
before the [*private-module-fragment*](module.private.frag#nt:private-module-fragment "10.5Private module fragment[module.private.frag]") in D (if any), and
- [(2.3)](#2.3)
either X is exported or else D and L are part of the same module andX does not inhabit a namespace with internal linkage or
declare a name with internal linkage[.](#2.sentence-3)
[*Note [2](#note-2)*:
Names declared by a [*using-declaration*](namespace.udecl#nt:using-declaration "9.10The using declaration[namespace.udecl]") have no linkage[.](#2.3.sentence-2)
— *end note*]
[*Note [3](#note-3)*:
A [*module-import-declaration*](module.import#nt:module-import-declaration "10.3Import declaration[module.import]") imports both
the named translation unit(s) and
any modules named by exported[*module-import-declaration*](module.import#nt:module-import-declaration "10.3Import declaration[module.import]")*s* within them,
recursively[.](#2.sentence-4)
[*Example [1](#example-1)*:
Translation unit #1:export module Q;export int sq(int i) { return i*i; }
Translation unit #2:export module R;export import Q;
Translation unit #3:import R;int main() { return sq(9); } // OK, sq from module Q — *end example*]
— *end note*]
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1702)
A [*single search*](#def:search,single "6.5.1General[basic.lookup.general]") in a scope S for a name N from a program point P finds all declarations that precede P to which any name that is the same as N ([[basic.pre]](basic.pre "6.1Preamble")) is bound in S[.](#3.sentence-1)
If any such declaration is a [*using-declarator*](namespace.udecl#nt:using-declarator "9.10The using declaration[namespace.udecl]") whose terminal name ([[expr.prim.id.unqual]](expr.prim.id.unqual "7.5.5.2Unqualified names"))
is not dependent ([[temp.dep.type]](temp.dep.type "13.8.3.2Dependent types")),
it is replaced by the declarations named by
the [*using-declarator*](namespace.udecl#nt:using-declarator "9.10The using declaration[namespace.udecl]") ([[namespace.udecl]](namespace.udecl "9.10The using declaration"))[.](#3.sentence-2)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1714)
In certain contexts, only certain kinds of declarations are included[.](#4.sentence-1)
After any such restriction, any declarations of classes or enumerations are discarded if any other declarations are found[.](#4.sentence-2)
[*Note [4](#note-4)*:
A type (but not a type alias or template)
is therefore hidden by any other entity in its scope[.](#4.sentence-3)
— *end note*]
However, if a lookup is [*type-only*](#def:lookup,type-only "6.5.1General[basic.lookup.general]"),
only declarations of
types and templates whose specializations are types are considered;
furthermore, if declarations
of a type alias and of its underlying entity are found,
the declaration of the type alias is discarded
instead of the type declaration[.](#4.sentence-4)

View File

@@ -0,0 +1,259 @@
[basic.lookup.qual]
# 6 Basics [[basic]](./#basic)
## 6.5 Name lookup [[basic.lookup]](basic.lookup#qual)
### 6.5.5 Qualified name lookup [basic.lookup.qual]
#### [6.5.5.1](#general) General [[basic.lookup.qual.general]](basic.lookup.qual.general)
[1](#general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2350)
Lookup of an [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") followed by a :: scope resolution operator
considers only
namespaces, types, and templates whose specializations are types[.](#general-1.sentence-1)
If a
name,[*template-id*](temp.names#nt:template-id "13.3Names of template specializations[temp.names]"),[*splice-scope-specifier*](expr.prim.id.qual#nt:splice-scope-specifier "7.5.5.3Qualified names[expr.prim.id.qual]"), or[*computed-type-specifier*](dcl.type.simple#nt:computed-type-specifier "9.2.9.3Simple type specifiers[dcl.type.simple]") is followed by a ::,
it shall either be
a dependent [*splice-scope-specifier*](expr.prim.id.qual#nt:splice-scope-specifier "7.5.5.3Qualified names[expr.prim.id.qual]") ([[temp.dep.splice]](temp.dep.splice "13.8.3.5Dependent splice specifiers")) or
it shall designate a namespace, class, enumeration, or dependent type,
and the :: is never interpreted as
a complete [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]")[.](#general-1.sentence-2)
[*Example [1](#general-example-1)*: class A {public:static int n;};int main() {int A;
A::n = 42; // OK A b; // error: A does not name a type}template<int> struct B : A {};namespace N {template<int> void B(); int f() {return B<0>::n; // error: N::B<0> is not a type}} — *end example*]
[2](#general-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2393)
A member-qualified name is
the (unique) component name ([[expr.prim.id.unqual]](expr.prim.id.unqual "7.5.5.2Unqualified names")), if any, of
- [(2.1)](#general-2.1)
an [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2Unqualified names[expr.prim.id.unqual]") or
- [(2.2)](#general-2.2)
a [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]") of the form[*type-name*](dcl.type.simple#nt:type-name "9.2.9.3Simple type specifiers[dcl.type.simple]") :: or [*namespace-name*](namespace.def.general#nt:namespace-name "9.9.2.1General[namespace.def.general]") ::
in the [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1General[expr.prim.id.general]") of a class member access expression ([[expr.ref]](expr.ref "7.6.1.5Class member access"))[.](#general-2.sentence-1)
A [*qualified name*](#def:name,qualified "6.5.5.1General[basic.lookup.qual.general]") is
- [(2.3)](#general-2.3)
a member-qualified name or
- [(2.4)](#general-2.4)
the terminal name of
* [(2.4.1)](#general-2.4.1)
a [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3Qualified names[expr.prim.id.qual]"),
* [(2.4.2)](#general-2.4.2)
a [*using-declarator*](namespace.udecl#nt:using-declarator "9.10The using declaration[namespace.udecl]"),
* [(2.4.3)](#general-2.4.3)
a [*typename-specifier*](temp.res.general#nt:typename-specifier "13.8.1General[temp.res.general]"),
* [(2.4.4)](#general-2.4.4)
a [*qualified-namespace-specifier*](namespace.alias#nt:qualified-namespace-specifier "9.9.3Namespace alias[namespace.alias]"), or
* [(2.4.5)](#general-2.4.5)
a [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]"),[*reflection-name*](expr.reflect#nt:reflection-name "7.6.2.10The reflection operator[expr.reflect]"),[*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5Elaborated type specifiers[dcl.type.elab]"), or[*class-or-decltype*](class.derived.general#nt:class-or-decltype "11.7.1General[class.derived.general]") that has a [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]") ([[expr.prim.id.qual]](expr.prim.id.qual "7.5.5.3Qualified names"))[.](#general-2.sentence-2)
The [*lookup context*](#def:lookup_context "6.5.5.1General[basic.lookup.qual.general]") of a member-qualified name is
the type of its associated object expression
(considered dependent if the object expression is type-dependent)[.](#general-2.sentence-3)
The lookup context of any other qualified name is
the type, template, or namespace
nominated by the preceding [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]")[.](#general-2.sentence-4)
[*Note [1](#general-note-1)*:
When parsing a class member access,
the name following the -> or . is
a qualified name even though it is not yet known of which kind[.](#general-2.sentence-5)
— *end note*]
[*Example [2](#general-example-2)*:
In N::C::m.Base::f()Base is a member-qualified name;
the other qualified names are C, m, and f[.](#general-2.sentence-6)
— *end example*]
[3](#general-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2440)
[*Qualified name lookup*](#def:lookup,qualified_name "6.5.5.1General[basic.lookup.qual.general]") in a class, namespace, or enumeration performs
a search of the scope associated with it ([[class.member.lookup]](class.member.lookup "6.5.2Member name lookup"))
except as specified below[.](#general-3.sentence-1)
Unless otherwise specified,
a qualified name undergoes qualified name lookup in its lookup context
from the point where it appears
unless the lookup context either
is dependent and is not the current instantiation ([[temp.dep.type]](temp.dep.type "13.8.3.2Dependent types")) or
is not a class or class template[.](#general-3.sentence-2)
If nothing is found by qualified lookup for a member-qualified name
that is the terminal name ([[expr.prim.id.unqual]](expr.prim.id.unqual "7.5.5.2Unqualified names")) of
a [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]") and
is not dependent, it undergoes unqualified lookup[.](#general-3.sentence-3)
[*Note [2](#general-note-2)*:
During lookup for a template specialization, no names are dependent[.](#general-3.sentence-4)
— *end note*]
[*Example [3](#general-example-3)*: int f();struct A {int B, C; template<int> using D = void; using T = void; void f();};using B = A;template<int> using C = A;template<int> using D = A;template<int> using X = A;
template<class T>void g(T *p) { // as instantiated for g<A>: p->X<0>::f(); // error: A::X not found in ((p->X) < 0) > ::f() p->template X<0>::f(); // OK, ::X found in definition context p->B::f(); // OK, non-type A::B ignored p->template C<0>::f(); // error: A::C is not a template p->template D<0>::f(); // error: A::D<0> is not a class type p->T::f(); // error: A::T is not a class type}template void g(A*); — *end example*]
[4](#general-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2485)
If a qualified name Q follows a ~:
- [(4.1)](#general-4.1)
If Q is a member-qualified name,
it undergoes unqualified lookup as well as qualified lookup[.](#general-4.1.sentence-1)
- [(4.2)](#general-4.2)
Otherwise, its [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]") N shall nominate a type[.](#general-4.2.sentence-1)
If N has another [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]") S,Q is looked up as if its lookup context were that nominated by S[.](#general-4.2.sentence-2)
- [(4.3)](#general-4.3)
Otherwise, if the terminal name of N is a member-qualified name M,Q is looked up as if ~Q appeared in place of M (as above)[.](#general-4.3.sentence-1)
- [(4.4)](#general-4.4)
Otherwise, Q undergoes unqualified lookup[.](#general-4.4.sentence-1)
- [(4.5)](#general-4.5)
Each lookup for Q considers only
types (if Q is not followed by a <) and
templates whose specializations are types[.](#general-4.5.sentence-1)
If it finds nothing or is ambiguous, it is discarded[.](#general-4.5.sentence-2)
- [(4.6)](#general-4.6)
The [*type-name*](dcl.type.simple#nt:type-name "9.2.9.3Simple type specifiers[dcl.type.simple]") that is or contains Q shall refer to its (original) lookup context (ignoring cv-qualification) under
the interpretation established by at least one (successful) lookup performed[.](#general-4.6.sentence-1)
[*Example [4](#general-example-4)*: struct C {typedef int I;};typedef int I1, I2;extern int* p;extern int* q;void f() { p->C::I::~I(); // I is looked up in the scope of C q->I1::~I2(); // I2 is found by unqualified lookup}struct A {~A();};typedef A AB;int main() { AB* p;
p->AB::~AB(); // explicitly calls the destructor for A} — *end example*]
#### [6.5.5.2](#class.qual) Class members [[class.qual]](class.qual)
[1](#class.qual-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2537)
In a lookup for a qualified name N whose lookup context is a class C in which function names are not ignored,[18](#footnote-18 "Lookups in which function names are ignored include names appearing in a nested-name-specifier, an elaborated-type-specifier, or a base-specifier.")
- [(1.1)](#class.qual-1.1)
if the search finds the injected-class-name of C ([[class.pre]](class.pre "11.1Preamble")), or
- [(1.2)](#class.qual-1.2)
if N is dependent and
is the terminal name of a [*using-declarator*](namespace.udecl#nt:using-declarator "9.10The using declaration[namespace.udecl]") ([[namespace.udecl]](namespace.udecl "9.10The using declaration"))
that names a constructor,
N is instead considered to name the constructor of class C[.](#class.qual-1.sentence-1)
Such a constructor name shall be used only
in the [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1General[dcl.decl.general]") of a (friend) declaration of a constructor or
in a [*using-declaration*](namespace.udecl#nt:using-declaration "9.10The using declaration[namespace.udecl]")[.](#class.qual-1.sentence-2)
[*Example [1](#class.qual-example-1)*: struct A { A(); };struct B: public A { B(); };
A::A() { } B::B() { } B::A ba; // object of type A A::A a; // error: A::A is not a type namestruct A::A a2; // object of type A — *end example*]
[18)](#footnote-18)[18)](#footnoteref-18)
Lookups in which
function names are ignored include names appearing in a[*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]"), an[*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5Elaborated type specifiers[dcl.type.elab]"), or a [*base-specifier*](class.derived.general#nt:base-specifier "11.7.1General[class.derived.general]")[.](#footnote-18.sentence-1)
#### [6.5.5.3](#namespace.qual) Namespace members [[namespace.qual]](namespace.qual)
[1](#namespace.qual-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2574)
Qualified name lookup in a namespace N additionally searches
every element of the inline namespace set of N ([[namespace.def]](namespace.def "9.9.2Namespace definition"))[.](#namespace.qual-1.sentence-1)
If nothing is found,
the results of the lookup are the results of qualified name lookup
in each namespace nominated by a [*using-directive*](namespace.udir#nt:using-directive "9.9.4Using namespace directive[namespace.udir]") that precedes the point of the lookup and
inhabits N or an element of N's inline namespace set[.](#namespace.qual-1.sentence-2)
[*Note [1](#namespace.qual-note-1)*:
If a [*using-directive*](namespace.udir#nt:using-directive "9.9.4Using namespace directive[namespace.udir]") refers to a namespace
that has already been considered, it does not affect the result[.](#namespace.qual-1.sentence-3)
— *end note*]
[*Example [1](#namespace.qual-example-1)*: int x;namespace Y {void f(float); void h(int);}namespace Z {void h(double);}namespace A {using namespace Y; void f(int); void g(int); int i;}namespace B {using namespace Z; void f(char); int i;}namespace AB {using namespace A; using namespace B; void g();}void h(){ AB::g(); // g is declared directly in AB, therefore S is { AB::g() } and AB::g() is chosen AB::f(1); // f is not declared directly in AB so the rules are applied recursively to A and B;// namespace Y is not searched and Y::f(float) is not considered;// S is { A::f(int), B::f(char) } and overload resolution chooses A::f(int) AB::f('c'); // as above but resolution chooses B::f(char) AB::x++; // x is not declared directly in AB, and is not declared in A or B, so the rules// are applied recursively to Y and Z, S is { } so the program is ill-formed AB::i++; // i is not declared directly in AB so the rules are applied recursively to A and B,// S is { A::i, B::i } so the use is ambiguous and the program is ill-formed AB::h(16.8); // h is not declared directly in AB and not declared directly in A or B so the rules// are applied recursively to Y and Z, S is { Y::h(int), Z::h(double) } and// overload resolution chooses Z::h(double)} — *end example*]
[2](#namespace.qual-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2640)
[*Note [2](#namespace.qual-note-2)*:
The same declaration found more than once is not an ambiguity (because
it is still a unique declaration)[.](#namespace.qual-2.sentence-1)
[*Example [2](#namespace.qual-example-2)*: namespace A {int a;}namespace B {using namespace A;}namespace C {using namespace A;}namespace BC {using namespace B; using namespace C;}void f(){ BC::a++; // OK, S is { A::a, A::a }}namespace D {using A::a;}namespace BD {using namespace B; using namespace D;}void g(){ BD::a++; // OK, S is { A::a, A::a }} — *end example*]
— *end note*]
[3](#namespace.qual-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2685)
[*Example [3](#namespace.qual-example-3)*:
Because each referenced namespace is searched at most once, the
following is well-defined:namespace B {int b;}namespace A {using namespace B; int a;}namespace B {using namespace A;}void f(){ A::a++; // OK, a declared directly in A, S is { A::a } B::a++; // OK, both A and B searched (once), S is { A::a } A::b++; // OK, both A and B searched (once), S is { B::b } B::b++; // OK, b declared directly in B, S is { B::b }}
— *end example*]
[4](#namespace.qual-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2713)
[*Note [3](#namespace.qual-note-3)*:
Class and enumeration declarations are not discarded
because of other declarations found in other searches[.](#namespace.qual-4.sentence-1)
— *end note*]
[*Example [4](#namespace.qual-example-4)*: namespace A {struct x { }; int x; int y;}namespace B {struct y { };}namespace C {using namespace A; using namespace B; int i = C::x; // OK, A::x (of type int)int j = C::y; // ambiguous, A::y or B::y} — *end example*]

View File

@@ -0,0 +1,166 @@
[basic.lookup.qual.general]
# 6 Basics [[basic]](./#basic)
## 6.5 Name lookup [[basic.lookup]](basic.lookup#qual.general)
### 6.5.5 Qualified name lookup [[basic.lookup.qual]](basic.lookup.qual#general)
#### 6.5.5.1 General [basic.lookup.qual.general]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2350)
Lookup of an [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") followed by a :: scope resolution operator
considers only
namespaces, types, and templates whose specializations are types[.](#1.sentence-1)
If a
name,[*template-id*](temp.names#nt:template-id "13.3Names of template specializations[temp.names]"),[*splice-scope-specifier*](expr.prim.id.qual#nt:splice-scope-specifier "7.5.5.3Qualified names[expr.prim.id.qual]"), or[*computed-type-specifier*](dcl.type.simple#nt:computed-type-specifier "9.2.9.3Simple type specifiers[dcl.type.simple]") is followed by a ::,
it shall either be
a dependent [*splice-scope-specifier*](expr.prim.id.qual#nt:splice-scope-specifier "7.5.5.3Qualified names[expr.prim.id.qual]") ([[temp.dep.splice]](temp.dep.splice "13.8.3.5Dependent splice specifiers")) or
it shall designate a namespace, class, enumeration, or dependent type,
and the :: is never interpreted as
a complete [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]")[.](#1.sentence-2)
[*Example [1](#example-1)*: class A {public:static int n;};int main() {int A;
A::n = 42; // OK A b; // error: A does not name a type}template<int> struct B : A {};namespace N {template<int> void B(); int f() {return B<0>::n; // error: N::B<0> is not a type}} — *end example*]
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2393)
A member-qualified name is
the (unique) component name ([[expr.prim.id.unqual]](expr.prim.id.unqual "7.5.5.2Unqualified names")), if any, of
- [(2.1)](#2.1)
an [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2Unqualified names[expr.prim.id.unqual]") or
- [(2.2)](#2.2)
a [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]") of the form[*type-name*](dcl.type.simple#nt:type-name "9.2.9.3Simple type specifiers[dcl.type.simple]") :: or [*namespace-name*](namespace.def.general#nt:namespace-name "9.9.2.1General[namespace.def.general]") ::
in the [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1General[expr.prim.id.general]") of a class member access expression ([[expr.ref]](expr.ref "7.6.1.5Class member access"))[.](#2.sentence-1)
A [*qualified name*](#def:name,qualified "6.5.5.1General[basic.lookup.qual.general]") is
- [(2.3)](#2.3)
a member-qualified name or
- [(2.4)](#2.4)
the terminal name of
* [(2.4.1)](#2.4.1)
a [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3Qualified names[expr.prim.id.qual]"),
* [(2.4.2)](#2.4.2)
a [*using-declarator*](namespace.udecl#nt:using-declarator "9.10The using declaration[namespace.udecl]"),
* [(2.4.3)](#2.4.3)
a [*typename-specifier*](temp.res.general#nt:typename-specifier "13.8.1General[temp.res.general]"),
* [(2.4.4)](#2.4.4)
a [*qualified-namespace-specifier*](namespace.alias#nt:qualified-namespace-specifier "9.9.3Namespace alias[namespace.alias]"), or
* [(2.4.5)](#2.4.5)
a [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]"),[*reflection-name*](expr.reflect#nt:reflection-name "7.6.2.10The reflection operator[expr.reflect]"),[*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5Elaborated type specifiers[dcl.type.elab]"), or[*class-or-decltype*](class.derived.general#nt:class-or-decltype "11.7.1General[class.derived.general]") that has a [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]") ([[expr.prim.id.qual]](expr.prim.id.qual "7.5.5.3Qualified names"))[.](#2.sentence-2)
The [*lookup context*](#def:lookup_context "6.5.5.1General[basic.lookup.qual.general]") of a member-qualified name is
the type of its associated object expression
(considered dependent if the object expression is type-dependent)[.](#2.sentence-3)
The lookup context of any other qualified name is
the type, template, or namespace
nominated by the preceding [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]")[.](#2.sentence-4)
[*Note [1](#note-1)*:
When parsing a class member access,
the name following the -> or . is
a qualified name even though it is not yet known of which kind[.](#2.sentence-5)
— *end note*]
[*Example [2](#example-2)*:
In N::C::m.Base::f()Base is a member-qualified name;
the other qualified names are C, m, and f[.](#2.sentence-6)
— *end example*]
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2440)
[*Qualified name lookup*](#def:lookup,qualified_name "6.5.5.1General[basic.lookup.qual.general]") in a class, namespace, or enumeration performs
a search of the scope associated with it ([[class.member.lookup]](class.member.lookup "6.5.2Member name lookup"))
except as specified below[.](#3.sentence-1)
Unless otherwise specified,
a qualified name undergoes qualified name lookup in its lookup context
from the point where it appears
unless the lookup context either
is dependent and is not the current instantiation ([[temp.dep.type]](temp.dep.type "13.8.3.2Dependent types")) or
is not a class or class template[.](#3.sentence-2)
If nothing is found by qualified lookup for a member-qualified name
that is the terminal name ([[expr.prim.id.unqual]](expr.prim.id.unqual "7.5.5.2Unqualified names")) of
a [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]") and
is not dependent, it undergoes unqualified lookup[.](#3.sentence-3)
[*Note [2](#note-2)*:
During lookup for a template specialization, no names are dependent[.](#3.sentence-4)
— *end note*]
[*Example [3](#example-3)*: int f();struct A {int B, C; template<int> using D = void; using T = void; void f();};using B = A;template<int> using C = A;template<int> using D = A;template<int> using X = A;
template<class T>void g(T *p) { // as instantiated for g<A>: p->X<0>::f(); // error: A::X not found in ((p->X) < 0) > ::f() p->template X<0>::f(); // OK, ::X found in definition context p->B::f(); // OK, non-type A::B ignored p->template C<0>::f(); // error: A::C is not a template p->template D<0>::f(); // error: A::D<0> is not a class type p->T::f(); // error: A::T is not a class type}template void g(A*); — *end example*]
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2485)
If a qualified name Q follows a ~:
- [(4.1)](#4.1)
If Q is a member-qualified name,
it undergoes unqualified lookup as well as qualified lookup[.](#4.1.sentence-1)
- [(4.2)](#4.2)
Otherwise, its [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]") N shall nominate a type[.](#4.2.sentence-1)
If N has another [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]") S,Q is looked up as if its lookup context were that nominated by S[.](#4.2.sentence-2)
- [(4.3)](#4.3)
Otherwise, if the terminal name of N is a member-qualified name M,Q is looked up as if ~Q appeared in place of M (as above)[.](#4.3.sentence-1)
- [(4.4)](#4.4)
Otherwise, Q undergoes unqualified lookup[.](#4.4.sentence-1)
- [(4.5)](#4.5)
Each lookup for Q considers only
types (if Q is not followed by a <) and
templates whose specializations are types[.](#4.5.sentence-1)
If it finds nothing or is ambiguous, it is discarded[.](#4.5.sentence-2)
- [(4.6)](#4.6)
The [*type-name*](dcl.type.simple#nt:type-name "9.2.9.3Simple type specifiers[dcl.type.simple]") that is or contains Q shall refer to its (original) lookup context (ignoring cv-qualification) under
the interpretation established by at least one (successful) lookup performed[.](#4.6.sentence-1)
[*Example [4](#example-4)*: struct C {typedef int I;};typedef int I1, I2;extern int* p;extern int* q;void f() { p->C::I::~I(); // I is looked up in the scope of C q->I1::~I2(); // I2 is found by unqualified lookup}struct A {~A();};typedef A AB;int main() { AB* p;
p->AB::~AB(); // explicitly calls the destructor for A} — *end example*]

View File

@@ -0,0 +1,14 @@
[basic.lookup.udir]
# 6 Basics [[basic]](./#basic)
## 6.5 Name lookup [[basic.lookup]](basic.lookup#udir)
### 6.5.7 Using-directives and namespace aliases [basic.lookup.udir]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2800)
In a [*using-directive*](namespace.udir#nt:using-directive "9.9.4Using namespace directive[namespace.udir]") or [*namespace-alias-definition*](namespace.alias#nt:namespace-alias-definition "9.9.3Namespace alias[namespace.alias]"),
during the lookup for a [*namespace-name*](namespace.def.general#nt:namespace-name "9.9.2.1General[namespace.def.general]") or for a name in a[*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]") only namespace names are considered[.](#1.sentence-1)

View File

@@ -0,0 +1,100 @@
[basic.lookup.unqual]
# 6 Basics [[basic]](./#basic)
## 6.5 Name lookup [[basic.lookup]](basic.lookup#unqual)
### 6.5.3 Unqualified name lookup [basic.lookup.unqual]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1972)
A [*using-directive*](namespace.udir#nt:using-directive "9.9.4Using namespace directive[namespace.udir]") is[*active*](#def:active) in a scope S at a program point P if it precedes P and inhabits either S or
the scope of a namespace nominated by a [*using-directive*](namespace.udir#nt:using-directive "9.9.4Using namespace directive[namespace.udir]") that is active in S at P[.](#1.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1979)
An [*unqualified search*](#def:unqualified_search) in a scope S from a program point P includes the results of searches from P in
- [(2.1)](#2.1)
S, and
- [(2.2)](#2.2)
for any scope U that contains P and is or is contained by S,
each namespace contained by S that is nominated by
a [*using-directive*](namespace.udir#nt:using-directive "9.9.4Using namespace directive[namespace.udir]") that is active in U at P[.](#2.sentence-1)
If no declarations are found,
the results of the unqualified search are
the results of an unqualified search in the parent scope of S, if any,
from P[.](#2.sentence-2)
[*Note [1](#note-1)*:
When a class scope is searched,
the scopes of its base classes are also searched ([[class.member.lookup]](class.member.lookup "6.5.2Member name lookup"))[.](#2.sentence-3)
If it inherits from a single base,
it is as if the scope of the base immediately contains
the scope of the derived class[.](#2.sentence-4)
Template parameter scopes
that are associated with one scope in the chain of parents
are also considered ([[temp.local]](temp.local "13.8.2Locally declared names"))[.](#2.sentence-5)
— *end note*]
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2005)
[*Unqualified name lookup*](#def:lookup,unqualified_name "6.5.3Unqualified name lookup[basic.lookup.unqual]") from a program point performs an unqualified search in its immediate scope[.](#3.sentence-1)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2009)
An [*unqualified name*](#def:name,unqualified "6.5.3Unqualified name lookup[basic.lookup.unqual]") is a name
that does not immediately follow a [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]") or
the . or -> in a class member access expression ([[expr.ref]](expr.ref "7.6.1.5Class member access")),
possibly after a template keyword or ~[.](#4.sentence-1)
Unless otherwise specified,
such a name undergoes unqualified name lookup from the point where it appears[.](#4.sentence-2)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2017)
An unqualified name that is a component name ([[expr.prim.id.unqual]](expr.prim.id.unqual "7.5.5.2Unqualified names")) of
a [*type-specifier*](dcl.type.general#nt:type-specifier "9.2.9.1General[dcl.type.general]") or [*ptr-operator*](dcl.decl.general#nt:ptr-operator "9.3.1General[dcl.decl.general]") of
a [*conversion-type-id*](class.conv.fct#nt:conversion-type-id "11.4.8.3Conversion functions[class.conv.fct]") is looked up in the same fashion
as the [*conversion-function-id*](class.conv.fct#nt:conversion-function-id "11.4.8.3Conversion functions[class.conv.fct]") in which it appears[.](#5.sentence-1)
If that lookup finds nothing, it undergoes unqualified name lookup;
in each case, only names
that denote types or templates whose specializations are types are considered[.](#5.sentence-2)
[*Example [1](#example-1)*: struct T1 { struct U { int i; }; };struct T2 { };struct U1 {};struct U2 {};
struct B {using T = T1; using U = U1; operator U1 T1::*(); operator U1 T2::*(); operator U2 T1::*(); operator U2 T2::*();};
template<class X, class T>int g() {using U = U2;
X().operator U T::*(); // #1, searches for T in the scope of X first X().operator U decltype(T())::*(); // #2return 0;}int x = g<B, T2>(); // #1 calls B::operator U1 T1::*// #2 calls B::operator U1 T2::* — *end example*]
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2053)
In a friend declaration [*declarator*](dcl.decl.general#nt:declarator "9.3.1General[dcl.decl.general]") whose [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1General[dcl.decl.general]") is a [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3Qualified names[expr.prim.id.qual]") whose lookup context ([[basic.lookup.qual]](basic.lookup.qual "6.5.5Qualified name lookup")) is a class or namespace S,
lookup for an unqualified name
that appears after the [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1General[dcl.decl.general]") performs a search in the scope associated with S[.](#6.sentence-1)
If that lookup finds nothing, it undergoes unqualified name lookup[.](#6.sentence-2)
[*Example [2](#example-2)*: using I = int;using D = double;namespace A {inline namespace N {using C = char; }using F = float; void f(I); void f(D); void f(C); void f(F);}struct X0 {using F = float; };struct W {using D = void; struct X : X0 {void g(I); void g(::D); void g(F); };};namespace B {typedef short I, F; class Y {friend void A::f(I); // error: no void A::f(short)friend void A::f(D); // OKfriend void A::f(C); // error: A::N::C not foundfriend void A::f(F); // OKfriend void W::X::g(I); // error: no void X::g(short)friend void W::X::g(D); // OKfriend void W::X::g(F); // OK};} — *end example*]

298
cppdraft/basic/lval.md Normal file
View File

@@ -0,0 +1,298 @@
[basic.lval]
# 7 Expressions [[expr]](./#expr)
## 7.2 Properties of expressions [[expr.prop]](expr.prop#basic.lval)
### 7.2.1 Value category [basic.lval]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L140)
Expressions are categorized according to the taxonomy in Figure [2](#fig:basic.lval)[.](#1.sentence-1)
![SVG Image](data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwLjAwIDAuMDAgMjc4LjAwIDEzNy4wMCIgaGVpZ2h0PSIxMzdwdCIgd2lkdGg9IjI3OHB0Ij4KPGcgY2xhc3M9ImdyYXBoIj4KY2F0ZWdvcmllcwoKPGcgY2xhc3M9Im5vZGUiPgpleHByZXNzaW9uCmV4cHJlc3Npb24KPC9nPgoKPGcgY2xhc3M9Im5vZGUiPgpnbHZhbHVlCmdsdmFsdWUKPC9nPgoKPGcgY2xhc3M9ImVkZ2UiPgpleHByZXNzaW9uLSZndDtnbHZhbHVlCjxwYXRoIGQ9Ik0xMjYuMDgsLTEwOS43NUMxMTguMjIsLTEwMi4wMyAxMDYuNTcsLTkwLjYgOTcuMDgsLTgxLjI4IiBzdHJva2U9ImJsYWNrIiBmaWxsPSJub25lIiAvPgo8cG9seWdvbiBmaWxsPSJibGFjayIgc3Ryb2tlPSJibGFjayIgLz4KPC9nPgoKPGcgY2xhc3M9Im5vZGUiPgpydmFsdWUKcnZhbHVlCjwvZz4KCjxnIGNsYXNzPSJlZGdlIj4KZXhwcmVzc2lvbi0mZ3Q7cnZhbHVlCjxwYXRoIGQ9Ik0xNDMuOTIsLTEwOS43NUMxNTEuNzgsLTEwMi4wMyAxNjMuNDMsLTkwLjYgMTcyLjkyLC04MS4yOCIgc3Ryb2tlPSJibGFjayIgZmlsbD0ibm9uZSIgLz4KPHBvbHlnb24gZmlsbD0iYmxhY2siIHN0cm9rZT0iYmxhY2siIC8+CjwvZz4KCjxnIGNsYXNzPSJub2RlIj4KbHZhbHVlCmx2YWx1ZQo8L2c+Cgo8ZyBjbGFzcz0iZWRnZSI+CmdsdmFsdWUtJmd0O2x2YWx1ZQo8cGF0aCBkPSJNNzIuMDgsLTU0Ljc1QzY0LjIyLC00Ny4wMyA1Mi41NywtMzUuNiA0My4wOCwtMjYuMjgiIHN0cm9rZT0iYmxhY2siIGZpbGw9Im5vbmUiIC8+Cjxwb2x5Z29uIGZpbGw9ImJsYWNrIiBzdHJva2U9ImJsYWNrIiAvPgo8L2c+Cgo8ZyBjbGFzcz0ibm9kZSI+Cnh2YWx1ZQp4dmFsdWUKPC9nPgoKPGcgY2xhc3M9ImVkZ2UiPgpnbHZhbHVlLSZndDt4dmFsdWUKPHBhdGggZD0iTTg5LjkyLC01NC43NUM5Ny43OCwtNDcuMDMgMTA5LjQzLC0zNS42IDExOC45MiwtMjYuMjgiIHN0cm9rZT0iYmxhY2siIGZpbGw9Im5vbmUiIC8+Cjxwb2x5Z29uIGZpbGw9ImJsYWNrIiBzdHJva2U9ImJsYWNrIiAvPgo8L2c+Cgo8ZyBjbGFzcz0iZWRnZSI+CnJ2YWx1ZS0mZ3Q7eHZhbHVlCjxwYXRoIHN0cm9rZT0iYmxhY2siIGZpbGw9Im5vbmUiIGQ9Ik0xODAuMDgsLTU0Ljc1QzE3Mi4yMiwtNDcuMDMgMTYwLjU3LC0zNS42IDE1MS4wOCwtMjYuMjgiIC8+Cjxwb2x5Z29uIGZpbGw9ImJsYWNrIiBzdHJva2U9ImJsYWNrIiAvPgo8L2c+Cgo8ZyBjbGFzcz0ibm9kZSI+CnBydmFsdWUKcHJ2YWx1ZQo8L2c+Cgo8ZyBjbGFzcz0iZWRnZSI+CnJ2YWx1ZS0mZ3Q7cHJ2YWx1ZQo8cGF0aCBzdHJva2U9ImJsYWNrIiBkPSJNMTk3LjkyLC01NC43NUMyMDUuNzgsLTQ3LjAzIDIxNy40MywtMzUuNiAyMjYuOTIsLTI2LjI4IiBmaWxsPSJub25lIiAvPgo8cG9seWdvbiBmaWxsPSJibGFjayIgc3Ryb2tlPSJibGFjayIgLz4KPC9nPgo8L2c+Cjwvc3ZnPg==)
Figure [2](#fig:basic.lval) — Expression category taxonomy [[fig:basic.lval]](./fig:basic.lval)
- [(1.1)](#1.1)
A [*glvalue*](#def:glvalue "7.2.1Value category[basic.lval]") is an expression whose evaluation determines the identity of an object, function, or non-static data member[.](#1.1.sentence-1)
- [(1.2)](#1.2)
A [*prvalue*](#def:prvalue "7.2.1Value category[basic.lval]") is an expression whose evaluation initializes an object
or computes the value of an operand of an operator,
as specified by the context in which it appears,
or an expression that has type cv void[.](#1.2.sentence-1)
- [(1.3)](#1.3)
An [*xvalue*](#def:xvalue "7.2.1Value category[basic.lval]") is a glvalue that denotes an object whose resources can be reused (usually because it is near the end of its lifetime)[.](#1.3.sentence-1)
- [(1.4)](#1.4)
An [*lvalue*](#def:lvalue "7.2.1Value category[basic.lval]") is a glvalue that is not an xvalue[.](#1.4.sentence-1)
- [(1.5)](#1.5)
An [*rvalue*](#def:rvalue "7.2.1Value category[basic.lval]") is a prvalue or an xvalue[.](#1.5.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L160)
Every expression belongs to exactly one of the fundamental categories in this
taxonomy: lvalue, xvalue, or prvalue[.](#2.sentence-1)
This property of an expression is called
its [*value category*](#def:value_category "7.2.1Value category[basic.lval]")[.](#2.sentence-2)
[*Note [1](#note-1)*:
The discussion of each built-in operator in[[expr.compound]](expr.compound "7.6Compound expressions") indicates the category of the value it yields and the value categories
of the operands it expects[.](#2.sentence-3)
For example, the built-in assignment operators expect that
the left operand is an lvalue and that the right operand is a prvalue and yield an
lvalue as the result[.](#2.sentence-4)
User-defined operators are functions, and the categories of
values they expect and yield are determined by their parameter and return types[.](#2.sentence-5)
— *end note*]
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L173)
[*Note [2](#note-2)*:
Historically, lvalues and rvalues were so-called
because they could appear on the left- and right-hand side of an assignment
(although this is no longer generally true);
glvalues are “generalized” lvalues,
prvalues are “pure” rvalues,
and xvalues are “eXpiring” lvalues[.](#3.sentence-1)
Despite their names, these terms apply to expressions, not values[.](#3.sentence-2)
— *end note*]
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L184)
[*Note [3](#note-3)*:
An expression is an xvalue if it is:
- [(4.1)](#4.1)
a move-eligible [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1General[expr.prim.id.general]") ([[expr.prim.id.unqual]](expr.prim.id.unqual "7.5.5.2Unqualified names"))
or [*splice-expression*](expr.prim.splice#nt:splice-expression "7.5.9Expression splicing[expr.prim.splice]") ([[expr.prim.splice]](expr.prim.splice "7.5.9Expression splicing")),
- [(4.2)](#4.2)
the result of calling a function, whether implicitly or explicitly,
whose return type is an rvalue reference to object type ([[expr.call]](expr.call "7.6.1.3Function call")),
- [(4.3)](#4.3)
a cast to an rvalue reference to
object type ([[expr.type.conv]](expr.type.conv "7.6.1.4Explicit type conversion (functional notation)"), [[expr.dynamic.cast]](expr.dynamic.cast "7.6.1.7Dynamic cast"), [[expr.static.cast]](expr.static.cast "7.6.1.9Static cast"), [[expr.reinterpret.cast]](expr.reinterpret.cast "7.6.1.10Reinterpret cast"), [[expr.const.cast]](expr.const.cast "7.6.1.11Const cast"), [[expr.cast]](expr.cast "7.6.3Explicit type conversion (cast notation)")),
- [(4.4)](#4.4)
a subscripting operation with an xvalue array operand ([[expr.sub]](expr.sub "7.6.1.2Subscripting")),
- [(4.5)](#4.5)
a class member access expression designating a non-static data member
of non-reference type
in which the object expression is an xvalue ([[expr.ref]](expr.ref "7.6.1.5Class member access")), or
- [(4.6)](#4.6)
a .* pointer-to-member expression in which the first operand is
an xvalue and the second operand is a pointer to data member ([[expr.mptr.oper]](expr.mptr.oper "7.6.4Pointer-to-member operators"))[.](#4.sentence-1)
In general, the effect of this rule is that named rvalue references are
treated as lvalues and unnamed rvalue references to objects are treated as
xvalues; rvalue references to functions are treated as lvalues whether named or not[.](#4.sentence-2)
— *end note*]
[*Example [1](#example-1)*: struct A {int m;};
A&& operator+(A, A);
A&& f();
A a;
A&& ar = static_cast<A&&>(a);
The expressions f(), f().m, static_cast<A&&>(a), and a + a are xvalues[.](#4.sentence-3)
The expression ar is an lvalue[.](#4.sentence-4)
— *end example*]
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L229)
The [*result*](#def:result,glvalue "7.2.1Value category[basic.lval]") of a glvalue is the entity denoted by the expression[.](#5.sentence-1)
The [*result*](#def:result,prvalue "7.2.1Value category[basic.lval]") of a prvalue
is the value that the expression stores into its context;
a prvalue that has type cv void has no result[.](#5.sentence-2)
A prvalue whose result is the value *V* is sometimes said to have or name the value *V*[.](#5.sentence-3)
The [*result object*](#def:result_object "7.2.1Value category[basic.lval]") of a prvalue is the object initialized by the prvalue;
a prvalue that has type cv void has no result object[.](#5.sentence-4)
[*Note [4](#note-4)*:
Except when the prvalue is the operand of a [*decltype-specifier*](dcl.type.decltype#nt:decltype-specifier "9.2.9.6Decltype specifiers[dcl.type.decltype]"),
a prvalue of object type always has a result object[.](#5.sentence-5)
For a discarded prvalue that has type other than cv void,
a temporary object is materialized; see [[expr.context]](expr.context "7.2.3Context dependence")[.](#5.sentence-6)
— *end note*]
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L246)
Whenever a glvalue appears as an operand of an operator that
requires a prvalue for that operand, the
lvalue-to-rvalue ([[conv.lval]](conv.lval "7.3.2Lvalue-to-rvalue conversion")), array-to-pointer ([[conv.array]](conv.array "7.3.3Array-to-pointer conversion")),
or function-to-pointer ([[conv.func]](conv.func "7.3.4Function-to-pointer conversion")) standard conversions are
applied to convert the expression to a prvalue[.](#6.sentence-1)
[*Note [5](#note-5)*:
An attempt to bind an rvalue reference to an lvalue is not such a context; see [[dcl.init.ref]](dcl.init.ref "9.5.4References")[.](#6.sentence-2)
— *end note*]
[*Note [6](#note-6)*:
Because cv-qualifiers are removed from the type of an expression of
non-class type when the expression is converted to a prvalue, an lvalue
of type const int can, for example, be used where
a prvalue of type int is required[.](#6.sentence-3)
— *end note*]
[*Note [7](#note-7)*:
There are no prvalue bit-fields; if a bit-field is converted to a
prvalue ([[conv.lval]](conv.lval "7.3.2Lvalue-to-rvalue conversion")), a prvalue of the type of the bit-field is
created, which might then be promoted ([[conv.prom]](conv.prom "7.3.7Integral promotions"))[.](#6.sentence-4)
— *end note*]
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L267)
Unless otherwise specified ([[expr.reinterpret.cast]](expr.reinterpret.cast "7.6.1.10Reinterpret cast"), [[expr.const.cast]](expr.const.cast "7.6.1.11Const cast")),
whenever a prvalue
that is not the result of the lvalue-to-rvalue conversion ([[conv.lval]](conv.lval "7.3.2Lvalue-to-rvalue conversion"))
appears as an operand of an operator,
the [temporary materialization conversion](conv.rval "7.3.5Temporary materialization conversion[conv.rval]") is
applied to convert the expression to an xvalue[.](#7.sentence-1)
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L275)
[*Note [8](#note-8)*:
The discussion of reference initialization in [[dcl.init.ref]](dcl.init.ref "9.5.4References") and of
temporaries in [[class.temporary]](class.temporary "6.8.7Temporary objects") indicates the behavior of lvalues
and rvalues in other significant contexts[.](#8.sentence-1)
— *end note*]
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L282)
Unless otherwise indicated ([[dcl.type.decltype]](dcl.type.decltype "9.2.9.6Decltype specifiers")),
a prvalue shall always have complete type or the void type;
if it has a class type or (possibly multidimensional) array of class type,
that class shall not be an abstract class ([[class.abstract]](class.abstract "11.7.4Abstract classes"))[.](#9.sentence-1)
A glvalue shall not have type cv void[.](#9.sentence-2)
[*Note [9](#note-9)*:
A glvalue can have complete or incomplete non-void type[.](#9.sentence-3)
Class and array prvalues can have cv-qualified types; other prvalues
always have cv-unqualified types[.](#9.sentence-4)
See [[expr.type]](expr.type "7.2.2Type")[.](#9.sentence-5)
— *end note*]
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L294)
An lvalue is [*modifiable*](#def:modifiable "7.2.1Value category[basic.lval]") unless its type is const-qualified
or is a function type[.](#10.sentence-1)
[*Note [10](#note-10)*:
A program that attempts
to modify an object through a nonmodifiable lvalue or through an rvalue
is ill-formed ([[expr.assign]](expr.assign "7.6.19Assignment and compound assignment operators"), [[expr.post.incr]](expr.post.incr "7.6.1.6Increment and decrement"), [[expr.pre.incr]](expr.pre.incr "7.6.2.3Increment and decrement"))[.](#10.sentence-2)
— *end note*]
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L303)
An object of dynamic type Tobj is[*type-accessible*](#def:type-accessible "7.2.1Value category[basic.lval]") through a glvalue of type Tref if Tref is similar ([[conv.qual]](conv.qual "7.3.6Qualification conversions")) to:
- [(11.1)](#11.1)
Tobj,
- [(11.2)](#11.2)
a type that is the signed or unsigned type corresponding to Tobj, or
- [(11.3)](#11.3)
a char, unsigned char, or std::byte type[.](#11.sentence-1)
If a program attempts to access ([[defns.access]](defns.access "3.1access"))
the stored value of an object through a glvalue
through which it is not type-accessible,
the behavior is undefined[.](#11.sentence-2)[42](#footnote-42 "The intent of this list is to specify those circumstances in which an object can or cannot be aliased.")
If a program invokes
a defaulted copy/move constructor or copy/move assignment operator
for a union of type U with a glvalue argument
that does not denote an object of type cv U within its lifetime,
the behavior is undefined[.](#11.sentence-3)
[*Note [11](#note-11)*:
In C, an entire object of structure type can be accessed, e.g., using assignment[.](#11.sentence-4)
By contrast, C++ has no notion of accessing an object of class type
through an lvalue of class type[.](#11.sentence-5)
— *end note*]
[42)](#footnote-42)[42)](#footnoteref-42)
The intent of this list is to specify those circumstances in which an
object can or cannot be aliased[.](#footnote-42.sentence-1)

1955
cppdraft/basic/memobj.md Normal file

File diff suppressed because it is too large Load Diff

384
cppdraft/basic/namespace.md Normal file
View File

@@ -0,0 +1,384 @@
[basic.namespace]
# 9 Declarations [[dcl]](./#dcl)
## 9.9 Namespaces [basic.namespace]
### [9.9.1](#general) General [[basic.namespace.general]](basic.namespace.general)
[1](#general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8189)
A namespace is an optionally-named entity
whose scope can contain declarations of any kind of entity[.](#general-1.sentence-1)
The name of a
namespace can be used to access entities that belong to that namespace;
that is, the [*members*](#def:member,namespace "9.9.1General[basic.namespace.general]") of the namespace[.](#general-1.sentence-2)
Unlike other entities,
the definition of a namespace can be split over several parts of one or
more translation units and modules[.](#general-1.sentence-3)
[2](#general-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8199)
[*Note [1](#general-note-1)*:
A [*namespace-definition*](#nt:namespace-definition "9.9.2.1General[namespace.def.general]") is exported
if it contains any[*export-declaration*](module.interface#nt:export-declaration "10.2Export declaration[module.interface]")*s* ([[module.interface]](module.interface "10.2Export declaration"))[.](#general-2.sentence-1)
A namespace is never attached to a named module
and never has a name with module linkage[.](#general-2.sentence-2)
— *end note*]
[*Example [1](#general-example-1)*: export module M;namespace N1 {} // N1 is not exportedexport namespace N2 {} // N2 is exportednamespace N3 { export int n; } // N3 is exported — *end example*]
[3](#general-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8216)
There is a [*global namespace*](#def:namespace,global "9.9.1General[basic.namespace.general]") with no declaration;
see [[basic.scope.namespace]](basic.scope.namespace "6.4.6Namespace scope")[.](#general-3.sentence-1)
The global namespace belongs to the global scope;
it is not an unnamed namespace ([[namespace.unnamed]](#namespace.unnamed "9.9.2.2Unnamed namespaces"))[.](#general-3.sentence-2)
[*Note [2](#general-note-2)*:
Lacking a declaration, it cannot be found by name lookup[.](#general-3.sentence-3)
— *end note*]
### [9.9.2](#namespace.def) Namespace definition [[namespace.def]](namespace.def)
#### [9.9.2.1](#namespace.def.general) General [[namespace.def.general]](namespace.def.general)
[namespace-name:](#nt:namespace-name "9.9.2.1General[namespace.def.general]")
[*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]")
[*namespace-alias*](#nt:namespace-alias "9.9.3Namespace alias[namespace.alias]")
[namespace-definition:](#nt:namespace-definition "9.9.2.1General[namespace.def.general]")
[*named-namespace-definition*](#nt:named-namespace-definition "9.9.2.1General[namespace.def.general]")
[*unnamed-namespace-definition*](#nt:unnamed-namespace-definition "9.9.2.1General[namespace.def.general]")
[*nested-namespace-definition*](#nt:nested-namespace-definition "9.9.2.1General[namespace.def.general]")
[named-namespace-definition:](#nt:named-namespace-definition "9.9.2.1General[namespace.def.general]")
inlineopt namespace [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")opt [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") { [*namespace-body*](#nt:namespace-body "9.9.2.1General[namespace.def.general]") }
[unnamed-namespace-definition:](#nt:unnamed-namespace-definition "9.9.2.1General[namespace.def.general]")
inlineopt namespace [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")opt { [*namespace-body*](#nt:namespace-body "9.9.2.1General[namespace.def.general]") }
[nested-namespace-definition:](#nt:nested-namespace-definition "9.9.2.1General[namespace.def.general]")
namespace [*enclosing-namespace-specifier*](#nt:enclosing-namespace-specifier "9.9.2.1General[namespace.def.general]") :: inlineopt [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") { [*namespace-body*](#nt:namespace-body "9.9.2.1General[namespace.def.general]") }
[enclosing-namespace-specifier:](#nt:enclosing-namespace-specifier "9.9.2.1General[namespace.def.general]")
[*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]")
[*enclosing-namespace-specifier*](#nt:enclosing-namespace-specifier "9.9.2.1General[namespace.def.general]") :: inlineopt [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]")
[namespace-body:](#nt:namespace-body "9.9.2.1General[namespace.def.general]")
[*declaration-seq*](dcl.pre#nt:declaration-seq "9.1Preamble[dcl.pre]")opt
[1](#namespace.def.general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8270)
Every [*namespace-definition*](#nt:namespace-definition "9.9.2.1General[namespace.def.general]") shall inhabit a namespace scope ([[basic.scope.namespace]](basic.scope.namespace "6.4.6Namespace scope"))[.](#namespace.def.general-1.sentence-1)
[2](#namespace.def.general-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8273)
In a [*named-namespace-definition*](#nt:named-namespace-definition "9.9.2.1General[namespace.def.general]") D,
the [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") is the name of the namespace[.](#namespace.def.general-2.sentence-1)
The [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") is looked up
by searching for it in the scopes of the namespace A in which D appears
and of every element of the inline namespace set of A[.](#namespace.def.general-2.sentence-2)
If the lookup finds a [*namespace-definition*](#nt:namespace-definition "9.9.2.1General[namespace.def.general]") for a namespace N,D [*extends*](#def:namespace,extend "9.9.2.1General[namespace.def.general]") N,
and the target scope of D is the scope to which N belongs[.](#namespace.def.general-2.sentence-3)
If the lookup finds nothing, the [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") is introduced
as a [*namespace-name*](#nt:namespace-name "9.9.2.1General[namespace.def.general]") into A[.](#namespace.def.general-2.sentence-4)
[3](#namespace.def.general-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8287)
Because a [*namespace-definition*](#nt:namespace-definition "9.9.2.1General[namespace.def.general]") contains[*declaration*](dcl.pre#nt:declaration "9.1Preamble[dcl.pre]")*s* in its [*namespace-body*](#nt:namespace-body "9.9.2.1General[namespace.def.general]") and a[*namespace-definition*](#nt:namespace-definition "9.9.2.1General[namespace.def.general]") is itself a [*declaration*](dcl.pre#nt:declaration "9.1Preamble[dcl.pre]"), it
follows that [*namespace-definition*](#nt:namespace-definition "9.9.2.1General[namespace.def.general]")*s* can be nested[.](#namespace.def.general-3.sentence-1)
[*Example [1](#namespace.def.general-example-1)*: namespace Outer {int i; namespace Inner {void f() { i++; } // Outer::iint i; void g() { i++; } // Inner::i}} — *end example*]
[4](#namespace.def.general-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8305)
If the optional initial inline keyword appears in a[*namespace-definition*](#nt:namespace-definition "9.9.2.1General[namespace.def.general]") for a particular namespace, that namespace is
declared to be an [*inline namespace*](#def:namespace,inline "9.9.2.1General[namespace.def.general]")[.](#namespace.def.general-4.sentence-1)
The inline keyword may be
used on a [*namespace-definition*](#nt:namespace-definition "9.9.2.1General[namespace.def.general]") that extends a namespace
only if it was previously used on the [*namespace-definition*](#nt:namespace-definition "9.9.2.1General[namespace.def.general]") that initially declared the [*namespace-name*](#nt:namespace-name "9.9.2.1General[namespace.def.general]") for that namespace[.](#namespace.def.general-4.sentence-2)
[5](#namespace.def.general-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8313)
The optional [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") in a [*named-namespace-definition*](#nt:named-namespace-definition "9.9.2.1General[namespace.def.general]") appertains to the namespace being defined or extended[.](#namespace.def.general-5.sentence-1)
[6](#namespace.def.general-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8318)
Members of an inline namespace can be used in most respects as though they were members
of the innermost enclosing namespace[.](#namespace.def.general-6.sentence-1)
Specifically, the inline namespace and its enclosing
namespace are both added to the set of associated namespaces used in[argument-dependent lookup](basic.lookup.argdep "6.5.4Argument-dependent name lookup[basic.lookup.argdep]") whenever one of them is,
and a [*using-directive*](#nt:using-directive "9.9.4Using namespace directive[namespace.udir]") ([[namespace.udir]](#namespace.udir "9.9.4Using namespace directive")) that names the inline
namespace is implicitly inserted into the enclosing namespace as for an unnamed
namespace ([[namespace.unnamed]](#namespace.unnamed "9.9.2.2Unnamed namespaces"))[.](#namespace.def.general-6.sentence-2)
Furthermore, each
member of the inline namespace can subsequently be partially
specialized ([[temp.spec.partial]](temp.spec.partial "13.7.6Partial specialization")), explicitly
instantiated ([[temp.explicit]](temp.explicit "13.9.3Explicit instantiation")), or explicitly specialized ([[temp.expl.spec]](temp.expl.spec "13.9.4Explicit specialization")) as
though it were a member of the enclosing namespace[.](#namespace.def.general-6.sentence-3)
Finally, looking up a name in the
enclosing namespace via explicit qualification ([[namespace.qual]](namespace.qual "6.5.5.3Namespace members")) will include
members of the inline namespace even if
there are declarations of that name in the enclosing namespace[.](#namespace.def.general-6.sentence-4)
[7](#namespace.def.general-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8334)
These properties are transitive: if a namespace N contains an inline namespaceM, which in turn contains an inline namespace O, then the members ofO can be used as though they were members of M or N[.](#namespace.def.general-7.sentence-1)
The [*inline namespace set*](#def:inline_namespace_set "9.9.2.1General[namespace.def.general]") of N is the transitive closure of all
inline namespaces in N[.](#namespace.def.general-7.sentence-2)
[8](#namespace.def.general-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8341)
A [*nested-namespace-definition*](#nt:nested-namespace-definition "9.9.2.1General[namespace.def.general]") with an[*enclosing-namespace-specifier*](#nt:enclosing-namespace-specifier "9.9.2.1General[namespace.def.general]") E,[*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") I and[*namespace-body*](#nt:namespace-body "9.9.2.1General[namespace.def.general]") B is equivalent tonamespace E { inlineopt namespace I { B } } where the optional inline is present if and only if
the [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") I is preceded by inline[.](#namespace.def.general-8.sentence-1)
[*Example [2](#namespace.def.general-example-2)*: namespace A::inline B::C {int i;}
The above has the same effect as:namespace A {inline namespace B {namespace C {int i; }}}
— *end example*]
#### [9.9.2.2](#namespace.unnamed) Unnamed namespaces [[namespace.unnamed]](namespace.unnamed)
[1](#namespace.unnamed-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8373)
An [*unnamed-namespace-definition*](#nt:unnamed-namespace-definition "9.9.2.1General[namespace.def.general]") behaves as if it were
replaced by
inlineopt namespace *unique* { /* empty body */ }
using namespace *unique* ;
namespace *unique* { [*namespace-body*](#nt:namespace-body "9.9.2.1General[namespace.def.general]") }
whereinline appears if and only if it appears in the[*unnamed-namespace-definition*](#nt:unnamed-namespace-definition "9.9.2.1General[namespace.def.general]") and all occurrences of *unique* in a translation unit are replaced by
the same identifier, and this identifier differs from all other
identifiers in the program[.](#namespace.unnamed-1.sentence-1)
The optional [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") in the [*unnamed-namespace-definition*](#nt:unnamed-namespace-definition "9.9.2.1General[namespace.def.general]") appertains to *unique*[.](#namespace.unnamed-1.sentence-2)
[*Example [1](#namespace.unnamed-example-1)*: namespace { int i; } // *unique*::ivoid f() { i++; } // *unique*::i++namespace A {namespace {int i; // A::*unique*::iint j; // A::*unique*::j}void g() { i++; } // A::*unique*::i++}using namespace A;void h() { i++; // error: *unique*::i or A::*unique*::i A::i++; // A::*unique*::i j++; // A::*unique*::j} — *end example*]
### [9.9.3](#namespace.alias) Namespace alias [[namespace.alias]](namespace.alias)
[1](#namespace.alias-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8417)
A [*namespace-alias-definition*](#nt:namespace-alias-definition "9.9.3Namespace alias[namespace.alias]") declares a [*namespace alias*](#def:alias,namespace "9.9.3Namespace alias[namespace.alias]") according to the following grammar:
[namespace-alias:](#nt:namespace-alias "9.9.3Namespace alias[namespace.alias]")
[*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]")
[namespace-alias-definition:](#nt:namespace-alias-definition "9.9.3Namespace alias[namespace.alias]")
namespace [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") = [*qualified-namespace-specifier*](#nt:qualified-namespace-specifier "9.9.3Namespace alias[namespace.alias]") ;
namespace [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") = [*splice-specifier*](basic.splice#nt:splice-specifier "6.6Splice specifiers[basic.splice]") ;
[qualified-namespace-specifier:](#nt:qualified-namespace-specifier "9.9.3Namespace alias[namespace.alias]")
[*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]")opt [*namespace-name*](#nt:namespace-name "9.9.2.1General[namespace.def.general]")
[2](#namespace.alias-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8436)
The [*splice-specifier*](basic.splice#nt:splice-specifier "6.6Splice specifiers[basic.splice]") (if any)
shall designate a namespace that is not the global namespace[.](#namespace.alias-2.sentence-1)
[3](#namespace.alias-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8440)
The [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") in a [*namespace-alias-definition*](#nt:namespace-alias-definition "9.9.3Namespace alias[namespace.alias]") becomes a [*namespace-alias*](#nt:namespace-alias "9.9.3Namespace alias[namespace.alias]")[.](#namespace.alias-3.sentence-1)
[4](#namespace.alias-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8444)
The underlying entity ([[basic.pre]](basic.pre "6.1Preamble")) of the namespace alias is
the namespace either
denoted by the [*qualified-namespace-specifier*](#nt:qualified-namespace-specifier "9.9.3Namespace alias[namespace.alias]") or
designated by the [*splice-specifier*](basic.splice#nt:splice-specifier "6.6Splice specifiers[basic.splice]")[.](#namespace.alias-4.sentence-1)
[*Note [1](#namespace.alias-note-1)*:
When looking up a [*namespace-name*](#nt:namespace-name "9.9.2.1General[namespace.def.general]") in a[*namespace-alias-definition*](#nt:namespace-alias-definition "9.9.3Namespace alias[namespace.alias]"), only namespace names are
considered, see [[basic.lookup.udir]](basic.lookup.udir "6.5.7Using-directives and namespace aliases")[.](#namespace.alias-4.sentence-2)
— *end note*]
### [9.9.4](#namespace.udir) Using namespace directive [[namespace.udir]](namespace.udir)
[using-directive:](#nt:using-directive "9.9.4Using namespace directive[namespace.udir]")
[*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")opt using namespace [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]")opt [*namespace-name*](#nt:namespace-name "9.9.2.1General[namespace.def.general]") ;
[*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")opt using namespace [*splice-specifier*](basic.splice#nt:splice-specifier "6.6Splice specifiers[basic.splice]") ;
[1](#namespace.udir-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8464)
The [*splice-specifier*](basic.splice#nt:splice-specifier "6.6Splice specifiers[basic.splice]") (if any) shall designate a namespace
that is not the global namespace[.](#namespace.udir-1.sentence-1)
The [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]"),[*namespace-name*](#nt:namespace-name "9.9.2.1General[namespace.def.general]"), and[*splice-specifier*](basic.splice#nt:splice-specifier "6.6Splice specifiers[basic.splice]") shall not be dependent[.](#namespace.udir-1.sentence-2)
[2](#namespace.udir-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8472)
A [*using-directive*](#nt:using-directive "9.9.4Using namespace directive[namespace.udir]") shall not appear in class scope, but may
appear in namespace scope or in block scope[.](#namespace.udir-2.sentence-1)
[*Note [1](#namespace.udir-note-1)*:
When looking up a [*namespace-name*](#nt:namespace-name "9.9.2.1General[namespace.def.general]") in a[*using-directive*](#nt:using-directive "9.9.4Using namespace directive[namespace.udir]"), only namespace names are considered,
see [[basic.lookup.udir]](basic.lookup.udir "6.5.7Using-directives and namespace aliases")[.](#namespace.udir-2.sentence-2)
— *end note*]
The optional [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") appertains to the [*using-directive*](#nt:using-directive "9.9.4Using namespace directive[namespace.udir]")[.](#namespace.udir-2.sentence-3)
[3](#namespace.udir-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8482)
[*Note [2](#namespace.udir-note-2)*:
A [*using-directive*](#nt:using-directive "9.9.4Using namespace directive[namespace.udir]") makes the names in the designated
namespace usable in the scope in which the[*using-directive*](#nt:using-directive "9.9.4Using namespace directive[namespace.udir]") appears after
the [*using-directive*](#nt:using-directive "9.9.4Using namespace directive[namespace.udir]") ([[basic.lookup.unqual]](basic.lookup.unqual "6.5.3Unqualified name lookup"), [[namespace.qual]](namespace.qual "6.5.5.3Namespace members"))[.](#namespace.udir-3.sentence-1)
During unqualified name lookup, the names
appear as if they were declared in the nearest enclosing namespace which
contains both the [*using-directive*](#nt:using-directive "9.9.4Using namespace directive[namespace.udir]") and the designated
namespace[.](#namespace.udir-3.sentence-2)
— *end note*]
[4](#namespace.udir-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8494)
[*Note [3](#namespace.udir-note-3)*:
A [*using-directive*](#nt:using-directive "9.9.4Using namespace directive[namespace.udir]") does not introduce any names[.](#namespace.udir-4.sentence-1)
— *end note*]
[*Example [1](#namespace.udir-example-1)*: namespace A {int i; namespace B {namespace C {int i; }using namespace A::B::C; void f1() { i = 5; // OK, C::i visible in B and hides A::i}}namespace D {using namespace B; using namespace C; void f2() { i = 5; // ambiguous, B::C::i or A::i?}}void f3() { i = 5; // uses A::i}}void f4() { i = 5; // error: neither i is visible} — *end example*]
[5](#namespace.udir-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8528)
[*Note [4](#namespace.udir-note-4)*:
A [*using-directive*](#nt:using-directive "9.9.4Using namespace directive[namespace.udir]") is transitive: if a scope contains a[*using-directive*](#nt:using-directive "9.9.4Using namespace directive[namespace.udir]") that designates a namespace that itself
contains [*using-directive*](#nt:using-directive "9.9.4Using namespace directive[namespace.udir]")*s*, the namespaces designated by those[*using-directive*](#nt:using-directive "9.9.4Using namespace directive[namespace.udir]")*s* are also eligible to be considered[.](#namespace.udir-5.sentence-1)
— *end note*]
[*Example [2](#namespace.udir-example-2)*: namespace M {int i;}namespace N {int i; using namespace M;}void f() {using namespace N;
i = 7; // error: both M::i and N::i are visible}
For another example,namespace A {int i;}namespace B {int i; int j; namespace C {namespace D {using namespace A; int j; int k; int a = i; // B::i hides A::i}using namespace D; int k = 89; // no problem yetint l = k; // ambiguous: C::k or D::kint m = i; // B::i hides A::iint n = j; // D::j hides B::j}}
— *end example*]
[6](#namespace.udir-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8578)
[*Note [5](#namespace.udir-note-5)*:
Declarations in a namespace
that appear after a [*using-directive*](#nt:using-directive "9.9.4Using namespace directive[namespace.udir]") for that namespace
can be found through that [*using-directive*](#nt:using-directive "9.9.4Using namespace directive[namespace.udir]") after they appear[.](#namespace.udir-6.sentence-1)
— *end note*]
[7](#namespace.udir-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8585)
[*Note [6](#namespace.udir-note-6)*:
If name lookup finds a declaration for a name in two different
namespaces, and the declarations do not declare the same entity and do
not declare functions or function templates, the use of the name is ill-formed ([[basic.lookup]](basic.lookup "6.5Name lookup"))[.](#namespace.udir-7.sentence-1)
In particular, the name of a variable, function or enumerator does not
hide the name of a class or enumeration declared in a different
namespace[.](#namespace.udir-7.sentence-2)
For example,namespace A {class X { }; extern "C" int g(); extern "C++" int h();}namespace B {void X(int); extern "C" int g(); extern "C++" int h(int);}using namespace A;using namespace B;
void f() { X(1); // error: name X found in two namespaces g(); // OK, name g refers to the same entity h(); // OK, overload resolution selects A::h}
— *end note*]
[8](#namespace.udir-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8615)
[*Note [7](#namespace.udir-note-7)*:
The order in which namespaces are considered and the
relationships among the namespaces implied by the[*using-directive*](#nt:using-directive "9.9.4Using namespace directive[namespace.udir]")*s* do not affect overload resolution[.](#namespace.udir-8.sentence-1)
Neither is any function excluded because another has the same
signature, even if one is in a namespace reachable through[*using-directive*](#nt:using-directive "9.9.4Using namespace directive[namespace.udir]")*s* in the namespace of the other[.](#namespace.udir-8.sentence-2)[83](#footnote-83 "During name lookup in a class hierarchy, some ambiguities can be resolved by considering whether one member hides the other along some paths ([class.member.lookup]). There is no such disambiguation when considering the set of names found as a result of following using-directives.")
— *end note*]
[*Example [3](#namespace.udir-example-3)*: namespace D {int d1; void f(char);}using namespace D;
int d1; // OK, no conflict with D::d1namespace E {int e; void f(int);}namespace D { // namespace extensionint d2; using namespace E; void f(int);}void f() { d1++; // error: ambiguous ::d1 or D::d1?::d1++; // OK D::d1++; // OK d2++; // OK, D::d2 e++; // OK, E::e f(1); // error: ambiguous: D::f(int) or E::f(int)? f('a'); // OK, D::f(char)} — *end example*]
[83)](#footnote-83)[83)](#footnoteref-83)
During
name lookup in a class hierarchy, some ambiguities can be
resolved by considering whether one member hides the other along some
paths ([[class.member.lookup]](class.member.lookup "6.5.2Member name lookup"))[.](#footnote-83.sentence-1)
There is no such disambiguation when
considering the set of names found as a result of following[*using-directive*](#nt:using-directive "9.9.4Using namespace directive[namespace.udir]")*s*[.](#footnote-83.sentence-2)

View File

@@ -0,0 +1,54 @@
[basic.namespace.general]
# 9 Declarations [[dcl]](./#dcl)
## 9.9 Namespaces [[basic.namespace]](basic.namespace#general)
### 9.9.1 General [basic.namespace.general]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8189)
A namespace is an optionally-named entity
whose scope can contain declarations of any kind of entity[.](#1.sentence-1)
The name of a
namespace can be used to access entities that belong to that namespace;
that is, the [*members*](#def:member,namespace "9.9.1General[basic.namespace.general]") of the namespace[.](#1.sentence-2)
Unlike other entities,
the definition of a namespace can be split over several parts of one or
more translation units and modules[.](#1.sentence-3)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8199)
[*Note [1](#note-1)*:
A [*namespace-definition*](namespace.def.general#nt:namespace-definition "9.9.2.1General[namespace.def.general]") is exported
if it contains any[*export-declaration*](module.interface#nt:export-declaration "10.2Export declaration[module.interface]")*s* ([[module.interface]](module.interface "10.2Export declaration"))[.](#2.sentence-1)
A namespace is never attached to a named module
and never has a name with module linkage[.](#2.sentence-2)
— *end note*]
[*Example [1](#example-1)*: export module M;namespace N1 {} // N1 is not exportedexport namespace N2 {} // N2 is exportednamespace N3 { export int n; } // N3 is exported — *end example*]
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8216)
There is a [*global namespace*](#def:namespace,global "9.9.1General[basic.namespace.general]") with no declaration;
see [[basic.scope.namespace]](basic.scope.namespace "6.4.6Namespace scope")[.](#3.sentence-1)
The global namespace belongs to the global scope;
it is not an unnamed namespace ([[namespace.unnamed]](namespace.unnamed "9.9.2.2Unnamed namespaces"))[.](#3.sentence-2)
[*Note [2](#note-2)*:
Lacking a declaration, it cannot be found by name lookup[.](#3.sentence-3)
— *end note*]

242
cppdraft/basic/pre.md Normal file
View File

@@ -0,0 +1,242 @@
[basic.pre]
# 6 Basics [[basic]](./#basic)
## 6.1 Preamble [basic.pre]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L13)
[*Note [1](#note-1)*:
This Clause presents the basic concepts of the C++ language[.](#1.sentence-1)
It explains the difference between an object and a
name and how they relate to the value categories for expressions[.](#1.sentence-2)
It introduces the concepts of a
declaration and a definition and presents C++'s
notion of type, scope, linkage, and
storage duration[.](#1.sentence-3)
The mechanisms for starting and
terminating a program are discussed[.](#1.sentence-4)
Finally, this Clause presents the
fundamental types of the language and lists the ways of constructing
compound types from these[.](#1.sentence-5)
— *end note*]
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L27)
[*Note [2](#note-2)*:
This Clause does not cover concepts that affect only a single
part of the language[.](#2.sentence-1)
Such concepts are discussed in the relevant
Clauses[.](#2.sentence-2)
— *end note*]
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L34)
A [*name*](basic.link#def:name "6.7Program and linkage[basic.link]") is an [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") ([[lex.name]](lex.name "5.11Identifiers")),[*conversion-function-id*](class.conv.fct#nt:conversion-function-id "11.4.8.3Conversion functions[class.conv.fct]") ([[class.conv.fct]](class.conv.fct "11.4.8.3Conversion functions")),[*operator-function-id*](over.oper.general#nt:operator-function-id "12.4.1General[over.oper.general]") ([[over.oper]](over.oper "12.4Overloaded operators")), or[*literal-operator-id*](over.literal#nt:literal-operator-id "12.6User-defined literals[over.literal]") ([[over.literal]](over.literal "12.6User-defined literals"))[.](#3.sentence-1)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L40)
Two names are [*the same*](#def:name,same "6.1Preamble[basic.pre]") if
- [(4.1)](#4.1)
they are [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]")*s* composed of the same character sequence, or
- [(4.2)](#4.2)
they are [*conversion-function-id*](class.conv.fct#nt:conversion-function-id "11.4.8.3Conversion functions[class.conv.fct]")*s* formed with
equivalent ([[temp.over.link]](temp.over.link "13.7.7.2Function template overloading")) types, or
- [(4.3)](#4.3)
they are [*operator-function-id*](over.oper.general#nt:operator-function-id "12.4.1General[over.oper.general]")*s* formed with
the same operator, or
- [(4.4)](#4.4)
they are [*literal-operator-id*](over.literal#nt:literal-operator-id "12.6User-defined literals[over.literal]")*s* formed with
the same literal suffix identifier[.](#4.sentence-1)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L52)
Every name is introduced by a [*declaration*](#def:declaration "6.1Preamble[basic.pre]"), which is a
- [(5.1)](#5.1)
[*name-declaration*](dcl.pre#nt:name-declaration "9.1Preamble[dcl.pre]"),[*block-declaration*](dcl.pre#nt:block-declaration "9.1Preamble[dcl.pre]"), or[*member-declaration*](class.mem.general#nt:member-declaration "11.4.1General[class.mem.general]") ([[dcl.pre]](dcl.pre "9.1Preamble"), [[class.mem]](class.mem "11.4Class members")),
- [(5.2)](#5.2)
[*init-declarator*](dcl.decl.general#nt:init-declarator "9.3.1General[dcl.decl.general]") ([[dcl.decl]](dcl.decl "9.3Declarators")),
- [(5.3)](#5.3)
[*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") in a structured binding declaration ([[dcl.struct.bind]](dcl.struct.bind "9.7Structured binding declarations")),
- [(5.4)](#5.4)
[*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") in a [*result-name-introducer*](dcl.contract.res#nt:result-name-introducer "9.4.2Referring to the result object[dcl.contract.res]") in a postcondition assertion ([[dcl.contract.res]](dcl.contract.res "9.4.2Referring to the result object")),
- [(5.5)](#5.5)
[*init-capture*](expr.prim.lambda.capture#nt:init-capture "7.5.6.3Captures[expr.prim.lambda.capture]") ([[expr.prim.lambda.capture]](expr.prim.lambda.capture "7.5.6.3Captures")),
- [(5.6)](#5.6)
[*condition*](stmt.pre#nt:condition "8.1Preamble[stmt.pre]") with a [*declarator*](dcl.decl.general#nt:declarator "9.3.1General[dcl.decl.general]") ([[stmt.pre]](stmt.pre "8.1Preamble")),
- [(5.7)](#5.7)
[*member-declarator*](class.mem.general#nt:member-declarator "11.4.1General[class.mem.general]") ([[class.mem]](class.mem "11.4Class members")),
- [(5.8)](#5.8)
[*using-declarator*](namespace.udecl#nt:using-declarator "9.10The using declaration[namespace.udecl]") ([[namespace.udecl]](namespace.udecl "9.10The using declaration")),
- [(5.9)](#5.9)
[*parameter-declaration*](dcl.fct#nt:parameter-declaration "9.3.4.6Functions[dcl.fct]") ([[dcl.fct]](dcl.fct "9.3.4.6Functions"), [[temp.param]](temp.param "13.2Template parameters")),
- [(5.10)](#5.10)
[*type-parameter*](temp.param#nt:type-parameter "13.2Template parameters[temp.param]") ([[temp.param]](temp.param "13.2Template parameters")),
- [(5.11)](#5.11)
[*type-tt-parameter*](temp.param#nt:type-tt-parameter "13.2Template parameters[temp.param]") ([[temp.param]](temp.param "13.2Template parameters")),
- [(5.12)](#5.12)
[*variable-tt-parameter*](temp.param#nt:variable-tt-parameter "13.2Template parameters[temp.param]") ([[temp.param]](temp.param "13.2Template parameters")),
- [(5.13)](#5.13)
[*concept-tt-parameter*](temp.param#nt:concept-tt-parameter "13.2Template parameters[temp.param]") ([[temp.param]](temp.param "13.2Template parameters")),
- [(5.14)](#5.14)
[*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5Elaborated type specifiers[dcl.type.elab]") that introduces a name ([[dcl.type.elab]](dcl.type.elab "9.2.9.5Elaborated type specifiers")),
- [(5.15)](#5.15)
[*class-specifier*](class.pre#nt:class-specifier "11.1Preamble[class.pre]") ([[class.pre]](class.pre "11.1Preamble")),
- [(5.16)](#5.16)
[*enum-specifier*](dcl.enum#nt:enum-specifier "9.8.1Enumeration declarations[dcl.enum]") or[*enumerator-definition*](dcl.enum#nt:enumerator-definition "9.8.1Enumeration declarations[dcl.enum]") ([[dcl.enum]](dcl.enum "9.8.1Enumeration declarations")),
- [(5.17)](#5.17)
[*exception-declaration*](except.pre#nt:exception-declaration "14.1Preamble[except.pre]") ([[except.pre]](except.pre "14.1Preamble")), or
- [(5.18)](#5.18)
implicit declaration of an injected-class-name ([[class.pre]](class.pre "11.1Preamble"))[.](#5.sentence-1)
[*Note [3](#note-3)*:
The term declaration is not a synonym for the grammar non-terminal [*declaration*](dcl.pre#nt:declaration "9.1Preamble[dcl.pre]") ([[dcl.pre]](dcl.pre "9.1Preamble"))[.](#5.sentence-2)
— *end note*]
[*Note [4](#note-4)*:
The interpretation of a [*for-range-declaration*](stmt.pre#nt:for-range-declaration "8.1Preamble[stmt.pre]") produces
one or more of the above ([[stmt.ranged]](stmt.ranged "8.6.5The range-based for statement"))[.](#5.sentence-3)
— *end note*]
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L107)
[*Note [5](#note-5)*:
Some names denote types or templates[.](#6.sentence-1)
In general, whenever a name is encountered
it is necessary to look it up ([[basic.lookup]](basic.lookup "6.5Name lookup"))
to determine whether that name denotes one of these entities
before continuing to parse the program that contains it[.](#6.sentence-2)
— *end note*]
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L116)
A [*variable*](#def:variable "6.1Preamble[basic.pre]") is introduced by the
declaration of
a reference other than a non-static data member or of
an object[.](#7.sentence-1)
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L122)
An [*entity*](#def:entity "6.1Preamble[basic.pre]") is a
variable,
structured binding,
result binding,
function,
enumerator,
type,
type alias,
non-static data member,
bit-field,
template,
namespace,
namespace alias,
template parameter,
function parameter, or[*init-capture*](expr.prim.lambda.capture#nt:init-capture "7.5.6.3Captures[expr.prim.lambda.capture]")[.](#8.sentence-1)
The [*underlying entity*](#def:entity,underlying "6.1Preamble[basic.pre]") of an entity is that entity
unless otherwise specified[.](#8.sentence-2)
A name [*denotes*](#def:denote "6.1Preamble[basic.pre]") the underlying entity of
the entity declared by each declaration that introduces the name[.](#8.sentence-3)
[*Note [6](#note-6)*:
Type aliases and namespace aliases have underlying entities
that are distinct from themselves[.](#8.sentence-4)
— *end note*]
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L148)
A [*local entity*](#def:entity,local "6.1Preamble[basic.pre]") is a variable with
automatic storage duration ([[basic.stc.auto]](basic.stc.auto "6.8.6.4Automatic storage duration")),
a structured binding ([[dcl.struct.bind]](dcl.struct.bind "9.7Structured binding declarations"))
whose corresponding variable is such an entity,
a result binding ([[dcl.contract.res]](dcl.contract.res "9.4.2Referring to the result object")),
or the *this object ([[expr.prim.this]](expr.prim.this "7.5.3This"))[.](#9.sentence-1)
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L156)
A name used in more than one translation unit can potentially
refer to the same entity in these translation units depending on the[linkage](basic.link "6.7Program and linkage[basic.link]") of the name specified in each
translation unit[.](#10.sentence-1)

711
cppdraft/basic/scope.md Normal file
View File

@@ -0,0 +1,711 @@
[basic.scope]
# 6 Basics [[basic]](./#basic)
## 6.4 Scope [basic.scope]
### [6.4.1](#scope) General [[basic.scope.scope]](basic.scope.scope)
[1](#scope-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L939)
The declarations in a program appear in a number of [*scopes*](#def:scope "6.4.1General[basic.scope.scope]") that are in general discontiguous[.](#scope-1.sentence-1)
The [*global scope*](#def:scope,global "6.4.1General[basic.scope.scope]") contains the entire program;
every other scope S is introduced by a
declaration,[*parameter-declaration-clause*](dcl.fct#nt:parameter-declaration-clause "9.3.4.6Functions[dcl.fct]"),[*statement*](stmt.pre#nt:statement "8.1Preamble[stmt.pre]"),[*handler*](except.pre#nt:handler "14.1Preamble[except.pre]"), or
contract assertion
(as described in the following subclauses of [basic.scope])
appearing in another scope, which thereby contains S[.](#scope-1.sentence-2)
An [*enclosing scope*](#def:scope,enclosing "6.4.1General[basic.scope.scope]") at a program point is any scope that contains it;
the smallest such scope is said to be the [*immediate scope*](#def:scope,immediate "6.4.1General[basic.scope.scope]") at that point[.](#scope-1.sentence-3)
A scope [*intervenes*](#def:scope,intervene "6.4.1General[basic.scope.scope]") between a program point P and a scope S (that does not contain P) if it is or contains S but does not contain P[.](#scope-1.sentence-4)
[2](#scope-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L958)
Unless otherwise specified:
- [(2.1)](#scope-2.1)
The smallest scope that contains a scope S is
the [*parent scope*](#def:scope,parent "6.4.1General[basic.scope.scope]") of S[.](#scope-2.1.sentence-1)
- [(2.2)](#scope-2.2)
No two declarations (re)introduce the same entity[.](#scope-2.2.sentence-1)
- [(2.3)](#scope-2.3)
A declaration [*inhabits*](#def:scope,inhabit "6.4.1General[basic.scope.scope]") the immediate scope at its locus ([[basic.scope.pdecl]](#pdecl "6.4.2Point of declaration"))[.](#scope-2.3.sentence-1)
- [(2.4)](#scope-2.4)
A declaration's [*target scope*](#def:scope,target "6.4.1General[basic.scope.scope]") is the scope it inhabits[.](#scope-2.4.sentence-1)
- [(2.5)](#scope-2.5)
Any names (re)introduced by a declaration are [*bound*](#def:name,bound "6.4.1General[basic.scope.scope]") to it
in its target scope[.](#scope-2.5.sentence-1)
The [*host scope*](#def:scope,host "6.4.1General[basic.scope.scope]") of a declaration is
the inhabited scope if that scope is a block scope and
the target scope otherwise[.](#scope-2.sentence-2)
An entity [*belongs*](#def:entity,belong "6.4.1General[basic.scope.scope]") to a scope S if S is the target scope of a declaration of the entity[.](#scope-2.sentence-3)
[*Note [1](#scope-note-1)*:
Special cases include that:
- [(2.6)](#scope-2.6)
Template parameter scopes are parents
only to other template parameter scopes ([[basic.scope.temp]](#temp "6.4.9Template parameter scope"))[.](#scope-2.6.sentence-1)
- [(2.7)](#scope-2.7)
Corresponding declarations with appropriate linkage
declare the same entity ([[basic.link]](basic.link "6.7Program and linkage"))[.](#scope-2.7.sentence-1)
- [(2.8)](#scope-2.8)
The declaration in a [*template-declaration*](temp.pre#nt:template-declaration "13.1Preamble[temp.pre]") inhabits the same scope as the [*template-declaration*](temp.pre#nt:template-declaration "13.1Preamble[temp.pre]")[.](#scope-2.8.sentence-1)
- [(2.9)](#scope-2.9)
Friend declarations and
declarations of template specializations do not bind names ([[dcl.meaning]](dcl.meaning "9.3.4Meaning of declarators"));
those with qualified names target a specified scope, and
other friend declarations and
certain [*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5Elaborated type specifiers[dcl.type.elab]")*s* ([[dcl.type.elab]](dcl.type.elab "9.2.9.5Elaborated type specifiers"))
target a larger enclosing scope[.](#scope-2.9.sentence-1)
- [(2.10)](#scope-2.10)
Block-scope extern or function declarations target a larger enclosing scope
but bind a name in their immediate scope ([[dcl.meaning.general]](dcl.meaning.general "9.3.4.1General"))[.](#scope-2.10.sentence-1)
- [(2.11)](#scope-2.11)
The names of unscoped enumerators are bound
in the two innermost enclosing scopes ([[dcl.enum]](dcl.enum "9.8.1Enumeration declarations"))[.](#scope-2.11.sentence-1)
- [(2.12)](#scope-2.12)
A class's name is also bound in its own scope ([[class.pre]](class.pre "11.1Preamble"))[.](#scope-2.12.sentence-1)
- [(2.13)](#scope-2.13)
The names of the members of an anonymous union are bound in
the union's parent scope ([[class.union.anon]](class.union.anon "11.5.2Anonymous unions"))[.](#scope-2.13.sentence-1)
— *end note*]
[3](#scope-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1013)
Two non-static member functions have[*corresponding object parameters*](#def:object_parameter,corresponding "6.4.1General[basic.scope.scope]") if
- [(3.1)](#scope-3.1)
exactly one is an implicit object member function
with no [*ref-qualifier*](dcl.decl.general#nt:ref-qualifier "9.3.1General[dcl.decl.general]") and
the types of their object parameters ([[dcl.fct]](dcl.fct "9.3.4.6Functions")),
after removing references,
are the same, or
- [(3.2)](#scope-3.2)
their object parameters have the same type[.](#scope-3.sentence-1)
Two non-static member function templates have[*corresponding object parameters*](#def:object_parameter,corresponding "6.4.1General[basic.scope.scope]") if
- [(3.3)](#scope-3.3)
exactly one is an implicit object member function
with no [*ref-qualifier*](dcl.decl.general#nt:ref-qualifier "9.3.1General[dcl.decl.general]") and
the types of their object parameters,
after removing any references,
are equivalent, or
- [(3.4)](#scope-3.4)
the types of their object parameters are equivalent[.](#scope-3.sentence-2)
Two function templates have[*corresponding signatures*](#def:signature,corresponding "6.4.1General[basic.scope.scope]") if
their [*template-parameter-list*](temp.pre#nt:template-parameter-list "13.1Preamble[temp.pre]")*s* have the same length,
their corresponding [*template-parameter*](temp.param#nt:template-parameter "13.2Template parameters[temp.param]")*s* are equivalent,
they have equivalent non-object-parameter-type-lists and return types (if any), and,
if both are non-static members, they have corresponding object parameters[.](#scope-3.sentence-3)
[4](#scope-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1048)
Two declarations [*correspond*](#def:correspond "6.4.1General[basic.scope.scope]") if they (re)introduce the same name,
both declare constructors, or
both declare destructors,
unless
- [(4.1)](#scope-4.1)
either is a [*using-declarator*](namespace.udecl#nt:using-declarator "9.10The using declaration[namespace.udecl]"), or
- [(4.2)](#scope-4.2)
one declares a type (not a type alias) and the other declares a
variable,
non-static data member other than of an anonymous union ([[class.union.anon]](class.union.anon "11.5.2Anonymous unions")),
enumerator,
function, or
function template, or
- [(4.3)](#scope-4.3)
each declares a function or function template
and they do not declare corresponding overloads[.](#scope-4.sentence-1)
Two function or function template declarations declare[*corresponding overloads*](#def:corresponding_overloads "6.4.1General[basic.scope.scope]") if
- [(4.4)](#scope-4.4)
both declare functions with the same non-object-parameter-type-list,[17](#footnote-17 "An implicit object parameter ([over.match.funcs]) is not part of the parameter-type-list.") equivalent ([[temp.over.link]](temp.over.link "13.7.7.2Function template overloading")) trailing [*requires-clause*](temp.pre#nt:requires-clause "13.1Preamble[temp.pre]")*s* (if any, except as specified in [[temp.friend]](temp.friend "13.7.5Friends")), and,
if both are non-static members,
they have corresponding object parameters, or
- [(4.5)](#scope-4.5)
both declare function templates with corresponding signatures and equivalent[*template-head*](temp.pre#nt:template-head "13.1Preamble[temp.pre]")*s* and
trailing [*requires-clause*](temp.pre#nt:requires-clause "13.1Preamble[temp.pre]")*s* (if any)[.](#scope-4.sentence-2)
[*Note [2](#scope-note-2)*:
Declarations can correspond even if neither binds a name[.](#scope-4.sentence-3)
[*Example [1](#scope-example-1)*: struct A {friend void f(); // #1};struct B {friend void f() {} // corresponds to, and defines, #1}; — *end example*]
— *end note*]
[*Example [2](#scope-example-2)*: typedef int Int;enum E : int { a };void f(int); // #1void f(Int) {} // defines #1void f(E) {} // OK, another overloadstruct X {static void f(); void f() const; // error: redeclarationvoid g(); void g() const; // OKvoid g() &; // error: redeclarationvoid h(this X&, int); void h(int) &&; // OK, another overloadvoid j(this const X&); void j() const &; // error: redeclarationvoid k(); void k(this X&); // error: redeclaration}; — *end example*]
[5](#scope-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1124)
A declaration is [*name-independent*](#def:declaration,name-independent "6.4.1General[basic.scope.scope]") if its name is _ (U+005f low line) and it declares
- [(5.1)](#scope-5.1)
a variable with automatic storage duration,
- [(5.2)](#scope-5.2)
a structured binding
with no [*storage-class-specifier*](dcl.stc#nt:storage-class-specifier "9.2.2Storage class specifiers[dcl.stc]") and
not inhabiting a namespace scope,
- [(5.3)](#scope-5.3)
a result binding ([[dcl.contract.res]](dcl.contract.res "9.4.2Referring to the result object")),
- [(5.4)](#scope-5.4)
the variable introduced by an [*init-capture*](expr.prim.lambda.capture#nt:init-capture "7.5.6.3Captures[expr.prim.lambda.capture]"), or
- [(5.5)](#scope-5.5)
a non-static data member of other than an anonymous union[.](#scope-5.sentence-1)
*Recommended practice*: Implementations should not emit a warning
that a name-independent declaration is used or unused[.](#scope-5.sentence-2)
[6](#scope-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1150)
Two declarations [*potentially conflict*](#def:potentially_conflict "6.4.1General[basic.scope.scope]") if they correspond and
cause their shared name to denote different entities ([[basic.link]](basic.link "6.7Program and linkage"))[.](#scope-6.sentence-1)
The program is ill-formed
if, in any scope, a name is bound to two declarations A and B that potentially conflict and A precedes B ([[basic.lookup]](basic.lookup "6.5Name lookup")),
unless B is name-independent[.](#scope-6.sentence-2)
[*Note [3](#scope-note-3)*:
An [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1General[expr.prim.id.general]") that names a unique name-independent declaration
is usable until an additional declaration of the same name
is introduced in the same scope ([[basic.lookup.general]](basic.lookup.general "6.5.1General"))[.](#scope-6.sentence-3)
— *end note*]
[*Note [4](#scope-note-4)*:
Overload resolution can consider potentially conflicting declarations
found in multiple scopes
(e.g., via [*using-directive*](namespace.udir#nt:using-directive "9.9.4Using namespace directive[namespace.udir]")*s* or for operator functions),
in which case it is often ambiguous[.](#scope-6.sentence-4)
— *end note*]
[*Example [3](#scope-example-3)*: void f() {int x,y; void x(); // error: different entity for xint y; // error: redefinition}enum { f }; // error: different entity for ::fnamespace A {}namespace B = A;namespace B = A; // OK, no effectnamespace B = B; // OK, no effectnamespace A = B; // OK, no effectnamespace B {} // error: different entity for Bvoid g() {int _;
_ = 0; // OKint _; // OK, name-independent declaration _ = 0; // error: two non-function declarations in the lookup set}void h () {int _; // #1 _ ++; // OKstatic int _; // error: conflicts with #1 because static variables are not name-independent} — *end example*]
[7](#scope-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1199)
A declaration is [*nominable*](#def:nominable "6.4.1General[basic.scope.scope]") in a class, class template, or namespace E at a point P if
it precedes P,
it does not inhabit a block scope, and
its target scope is the scope associated with E or,
if E is a namespace,
any element of the inline namespace set of E ([[namespace.def]](namespace.def "9.9.2Namespace definition"))[.](#scope-7.sentence-1)
[*Example [4](#scope-example-4)*: namespace A {void f() {void g();}inline namespace B {struct S {friend void h(); static int i; }; }}
At the end of this example,
the declarations of f, B, S, and h are nominable in A, but those of g and i are not[.](#scope-7.sentence-2)
— *end example*]
[8](#scope-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1225)
When instantiating a templated entity ([[temp.pre]](temp.pre "13.1Preamble")),
any scope S introduced by any part of the template definition is considered
to be introduced by the instantiated entity and
to contain the instantiations of any declarations that inhabit S[.](#scope-8.sentence-1)
[17)](#footnote-17)[17)](#footnoteref-17)
An implicit object parameter ([[over.match.funcs]](over.match.funcs "12.2.2Candidate functions and argument lists"))
is not part of the parameter-type-list[.](#footnote-17.sentence-1)
### [6.4.2](#pdecl) Point of declaration [[basic.scope.pdecl]](basic.scope.pdecl)
[1](#pdecl-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1237)
The [*locus*](#def:locus "6.4.2Point of declaration[basic.scope.pdecl]") of a declaration ([[basic.pre]](basic.pre "6.1Preamble")) that is a declarator
is immediately after the complete declarator ([[dcl.decl]](dcl.decl "9.3Declarators"))[.](#pdecl-1.sentence-1)
[*Example [1](#pdecl-example-1)*: unsigned char x = 12;{ unsigned char x = x; }
Here, the initialization of the second x has undefined behavior,
because the initializer accesses the second x outside its lifetime ([[basic.life]](basic.life "6.8.4Lifetime"))[.](#pdecl-1.sentence-2)
— *end example*]
[2](#pdecl-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1251)
[*Note [1](#pdecl-note-1)*:
A name from an outer scope remains visible up to
the locus of the declaration that hides it[.](#pdecl-2.sentence-1)
[*Example [2](#pdecl-example-2)*:
const int i = 2;{ int i[i]; } declares a block-scope array of two integers[.](#pdecl-2.sentence-2)
— *end example*]
— *end note*]
[3](#pdecl-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1265)
The locus of a [*class-specifier*](class.pre#nt:class-specifier "11.1Preamble[class.pre]") is immediately after
the [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") or [*simple-template-id*](temp.names#nt:simple-template-id "13.3Names of template specializations[temp.names]") (if any)
in its [*class-head*](class.pre#nt:class-head "11.1Preamble[class.pre]") ([[class.pre]](class.pre "11.1Preamble"))[.](#pdecl-3.sentence-1)
The locus of an [*enum-specifier*](dcl.enum#nt:enum-specifier "9.8.1Enumeration declarations[dcl.enum]") is immediately after
its [*enum-head*](dcl.enum#nt:enum-head "9.8.1Enumeration declarations[dcl.enum]");
the locus of an [*opaque-enum-declaration*](dcl.enum#nt:opaque-enum-declaration "9.8.1Enumeration declarations[dcl.enum]") is immediately after it ([[dcl.enum]](dcl.enum "9.8.1Enumeration declarations"))[.](#pdecl-3.sentence-2)
The locus of an [*alias-declaration*](dcl.pre#nt:alias-declaration "9.1Preamble[dcl.pre]") is immediately after it[.](#pdecl-3.sentence-3)
[4](#pdecl-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1277)
The locus of a [*using-declarator*](namespace.udecl#nt:using-declarator "9.10The using declaration[namespace.udecl]") that does not name a constructor
is immediately after the [*using-declarator*](namespace.udecl#nt:using-declarator "9.10The using declaration[namespace.udecl]") ([[namespace.udecl]](namespace.udecl "9.10The using declaration"))[.](#pdecl-4.sentence-1)
[5](#pdecl-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1282)
The locus of an [*enumerator-definition*](dcl.enum#nt:enumerator-definition "9.8.1Enumeration declarations[dcl.enum]") is immediately after it[.](#pdecl-5.sentence-1)
[*Example [3](#pdecl-example-3)*: const int x = 12;{ enum { x = x }; }
Here, the enumerator x is initialized with the value of the
constant x, namely 12[.](#pdecl-5.sentence-2)
— *end example*]
[6](#pdecl-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1293)
[*Note [2](#pdecl-note-2)*:
After the declaration of a class member,
the member name can be found in the scope of its class
even if the class is an incomplete class[.](#pdecl-6.sentence-1)
[*Example [4](#pdecl-example-4)*: struct X {enum E { z = 16 }; int b[X::z]; // OK}; — *end example*]
— *end note*]
[7](#pdecl-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1309)
The locus of an [*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5Elaborated type specifiers[dcl.type.elab]") that is a declaration ([[dcl.type.elab]](dcl.type.elab "9.2.9.5Elaborated type specifiers")) is immediately after it[.](#pdecl-7.sentence-1)
[8](#pdecl-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1313)
The locus of an injected-class-name declaration ([[class.pre]](class.pre "11.1Preamble"))
is immediately following the opening brace of the class definition[.](#pdecl-8.sentence-1)
[9](#pdecl-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1317)
The locus of the implicit declaration of
a function-local predefined variable ([[dcl.fct.def.general]](dcl.fct.def.general "9.6.1General"))
is immediately before
the [*function-body*](dcl.fct.def.general#nt:function-body "9.6.1General[dcl.fct.def.general]") of its function's definition[.](#pdecl-9.sentence-1)
[10](#pdecl-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1323)
The locus of the declaration of a structured binding ([[dcl.struct.bind]](dcl.struct.bind "9.7Structured binding declarations"))
is immediately after
the [*identifier-list*](cpp.pre#nt:identifier-list "15.1Preamble[cpp.pre]") of the structured binding declaration[.](#pdecl-10.sentence-1)
[11](#pdecl-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1328)
The locus of a [*for-range-declaration*](stmt.pre#nt:for-range-declaration "8.1Preamble[stmt.pre]") of a range-based for statement ([[stmt.ranged]](stmt.ranged "8.6.5The range-based for statement"))
is immediately after the [*for-range-initializer*](stmt.pre#nt:for-range-initializer "8.1Preamble[stmt.pre]")[.](#pdecl-11.sentence-1)
The locus of a [*for-range-declaration*](stmt.pre#nt:for-range-declaration "8.1Preamble[stmt.pre]") of an expansion statement ([[stmt.expand]](stmt.expand "8.7Expansion statements"))
is immediately after the [*expansion-initializer*](stmt.expand#nt:expansion-initializer "8.7Expansion statements[stmt.expand]")[.](#pdecl-11.sentence-2)
[12](#pdecl-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1336)
The locus of a [*template-parameter*](temp.param#nt:template-parameter "13.2Template parameters[temp.param]") is immediately after it[.](#pdecl-12.sentence-1)
[*Example [5](#pdecl-example-5)*: typedef unsigned char T;template<class T = T // lookup finds the [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4The typedef specifier[dcl.typedef]") , T // lookup finds the template parameter N = 0> struct A { }; — *end example*]
[13](#pdecl-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1348)
The locus of a [*result-name-introducer*](dcl.contract.res#nt:result-name-introducer "9.4.2Referring to the result object[dcl.contract.res]") ([[dcl.contract.res]](dcl.contract.res "9.4.2Referring to the result object"))
is immediately after it[.](#pdecl-13.sentence-1)
[14](#pdecl-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1352)
The locus of a [*concept-definition*](temp.concept#nt:concept-definition "13.7.9Concept definitions[temp.concept]") is immediately after its [*concept-name*](temp.concept#nt:concept-name "13.7.9Concept definitions[temp.concept]") ([[temp.concept]](temp.concept "13.7.9Concept definitions"))[.](#pdecl-14.sentence-1)
[*Note [3](#pdecl-note-3)*:
The [*constraint-expression*](temp.constr.decl#nt:constraint-expression "13.5.3Constrained declarations[temp.constr.decl]") cannot use
the [*concept-name*](temp.concept#nt:concept-name "13.7.9Concept definitions[temp.concept]")[.](#pdecl-14.sentence-2)
— *end note*]
[15](#pdecl-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1360)
The locus of a [*namespace-definition*](namespace.def.general#nt:namespace-definition "9.9.2.1General[namespace.def.general]") with an [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") is immediately after the [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]")[.](#pdecl-15.sentence-1)
[*Note [4](#pdecl-note-4)*:
An identifier is invented
for an [*unnamed-namespace-definition*](namespace.def.general#nt:unnamed-namespace-definition "9.9.2.1General[namespace.def.general]") ([[namespace.unnamed]](namespace.unnamed "9.9.2.2Unnamed namespaces"))[.](#pdecl-15.sentence-2)
— *end note*]
[16](#pdecl-16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1369)
[*Note [5](#pdecl-note-5)*:
Friend declarations can introduce functions or classes
that belong to the nearest enclosing namespace or block scope,
but they do not bind names anywhere ([[class.friend]](class.friend "11.8.4Friends"))[.](#pdecl-16.sentence-1)
Function declarations at block scope and
variable declarations with the extern specifier at block scope
declare entities
that belong to the nearest enclosing namespace,
but they do not bind names in it[.](#pdecl-16.sentence-2)
— *end note*]
[17](#pdecl-17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1381)
[*Note [6](#pdecl-note-6)*:
For point of instantiation of a template, see [[temp.point]](temp.point "13.8.4.1Point of instantiation")[.](#pdecl-17.sentence-1)
— *end note*]
### [6.4.3](#block) Block scope [[basic.scope.block]](basic.scope.block)
[1](#block-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1391)
Each
- [(1.1)](#block-1.1)
selection, iteration, or expansion statement ([[stmt.select]](stmt.select "8.5Selection statements"), [[stmt.iter]](stmt.iter "8.6Iteration statements"), [[stmt.expand]](stmt.expand "8.7Expansion statements")),
- [(1.2)](#block-1.2)
substatement of such a statement,
- [(1.3)](#block-1.3)
[*handler*](except.pre#nt:handler "14.1Preamble[except.pre]") ([[except.pre]](except.pre "14.1Preamble")), or
- [(1.4)](#block-1.4)
compound statement ([[stmt.block]](stmt.block "8.4Compound statement or block"))
that is not the [*compound-statement*](stmt.block#nt:compound-statement "8.4Compound statement or block[stmt.block]") of a [*handler*](except.pre#nt:handler "14.1Preamble[except.pre]")
introduces a [*block scope*](#def:scope,block "6.4.3Block scope[basic.scope.block]") that includes that statement or [*handler*](except.pre#nt:handler "14.1Preamble[except.pre]")[.](#block-1.sentence-1)
[*Note [1](#block-note-1)*:
A substatement that is also a block has only one scope[.](#block-1.sentence-2)
— *end note*]
A variable that belongs to a block scope is a [*block variable*](#def:block_variable "6.4.3Block scope[basic.scope.block]")[.](#block-1.sentence-3)
[*Example [1](#block-example-1)*: int i = 42;int a[10];
for (int i = 0; i < 10; i++) a[i] = i;
int j = i; // j = 42 — *end example*]
[2](#block-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1423)
If a declaration
that is not a name-independent declaration and
that binds a name in the block scope S of a
- [(2.1)](#block-2.1)
[*compound-statement*](stmt.block#nt:compound-statement "8.4Compound statement or block[stmt.block]") of a [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1General[expr.prim.lambda.general]"),[*function-body*](dcl.fct.def.general#nt:function-body "9.6.1General[dcl.fct.def.general]"), or [*function-try-block*](except.pre#nt:function-try-block "14.1Preamble[except.pre]"),
- [(2.2)](#block-2.2)
substatement of a selection or iteration statement
that is not itself a selection or iteration statement, or
- [(2.3)](#block-2.3)
[*handler*](except.pre#nt:handler "14.1Preamble[except.pre]") of a [*function-try-block*](except.pre#nt:function-try-block "14.1Preamble[except.pre]")
potentially conflicts with a declaration
whose target scope is the parent scope of S,
the program is ill-formed[.](#block-2.sentence-1)
[*Example [2](#block-example-2)*: if (int x = f()) {int x; // error: redeclaration of x}else {int x; // error: redeclaration of x} — *end example*]
### [6.4.4](#param) Function parameter scope [[basic.scope.param]](basic.scope.param)
[1](#param-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1456)
A [*parameter-declaration-clause*](dcl.fct#nt:parameter-declaration-clause "9.3.4.6Functions[dcl.fct]") P introduces
a [*function parameter scope*](#def:scope,function_parameter "6.4.4Function parameter scope[basic.scope.param]") that includes P[.](#param-1.sentence-1)
[*Note [1](#param-note-1)*:
A function parameter cannot be used for its value
within the [*parameter-declaration-clause*](dcl.fct#nt:parameter-declaration-clause "9.3.4.6Functions[dcl.fct]") ([[dcl.fct.default]](dcl.fct.default "9.3.4.7Default arguments"))[.](#param-1.sentence-2)
— *end note*]
- [(1.1)](#param-1.1)
If P is associated with a [*declarator*](dcl.decl.general#nt:declarator "9.3.1General[dcl.decl.general]") and
is preceded by a (possibly-parenthesized) [*noptr-declarator*](dcl.decl.general#nt:noptr-declarator "9.3.1General[dcl.decl.general]") of
the form[*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1General[dcl.decl.general]") [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")opt,
its scope extends to the end of the nearest enclosing[*init-declarator*](dcl.decl.general#nt:init-declarator "9.3.1General[dcl.decl.general]"),[*member-declarator*](class.mem.general#nt:member-declarator "11.4.1General[class.mem.general]"),[*declarator*](dcl.decl.general#nt:declarator "9.3.1General[dcl.decl.general]") of a [*parameter-declaration*](dcl.fct#nt:parameter-declaration "9.3.4.6Functions[dcl.fct]") or
a [*nodeclspec-function-declaration*](dcl.pre#nt:nodeclspec-function-declaration "9.1Preamble[dcl.pre]"), or[*function-definition*](dcl.fct.def.general#nt:function-definition "9.6.1General[dcl.fct.def.general]"),
but does not include the locus of the associated [*declarator*](dcl.decl.general#nt:declarator "9.3.1General[dcl.decl.general]")[.](#param-1.1.sentence-1)
[*Note [2](#param-note-2)*:
In this case, P declares the parameters of a function
(or a function or template parameter declared with function type)[.](#param-1.1.sentence-2)
A member function's parameter scope is nested within its class's scope[.](#param-1.1.sentence-3)
— *end note*]
- [(1.2)](#param-1.2)
If P is associated with a [*lambda-declarator*](expr.prim.lambda.general#nt:lambda-declarator "7.5.6.1General[expr.prim.lambda.general]"),
its scope extends to the end of the [*compound-statement*](stmt.block#nt:compound-statement "8.4Compound statement or block[stmt.block]") in the [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1General[expr.prim.lambda.general]")[.](#param-1.2.sentence-1)
- [(1.3)](#param-1.3)
If P is associated with a [*requirement-parameter-list*](expr.prim.req.general#nt:requirement-parameter-list "7.5.8.1General[expr.prim.req.general]"),
its scope extends to the end of the [*requirement-body*](expr.prim.req.general#nt:requirement-body "7.5.8.1General[expr.prim.req.general]") of the [*requires-expression*](expr.prim.req.general#nt:requires-expression "7.5.8.1General[expr.prim.req.general]")[.](#param-1.3.sentence-1)
- [(1.4)](#param-1.4)
If P is associated with a [*deduction-guide*](temp.deduct.guide#nt:deduction-guide "13.7.2.3Deduction guides[temp.deduct.guide]"),
its scope extends to the end of the [*deduction-guide*](temp.deduct.guide#nt:deduction-guide "13.7.2.3Deduction guides[temp.deduct.guide]")[.](#param-1.4.sentence-1)
### [6.4.5](#lambda) Lambda scope [[basic.scope.lambda]](basic.scope.lambda)
A [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1General[expr.prim.lambda.general]") E introduces a [*lambda scope*](#def:scope,lambda "6.4.5Lambda scope[basic.scope.lambda]") that starts immediately after the [*lambda-introducer*](expr.prim.lambda.general#nt:lambda-introducer "7.5.6.1General[expr.prim.lambda.general]") of E and extends to the end of the [*compound-statement*](stmt.block#nt:compound-statement "8.4Compound statement or block[stmt.block]") of E[.](#lambda-sentence-1)
### [6.4.6](#namespace) Namespace scope [[basic.scope.namespace]](basic.scope.namespace)
[1](#namespace-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1501)
Any [*namespace-definition*](namespace.def.general#nt:namespace-definition "9.9.2.1General[namespace.def.general]") for a namespace N introduces
a [*namespace scope*](#def:scope,namespace "6.4.6Namespace scope[basic.scope.namespace]") that includes the [*namespace-body*](namespace.def.general#nt:namespace-body "9.9.2.1General[namespace.def.general]") for every [*namespace-definition*](namespace.def.general#nt:namespace-definition "9.9.2.1General[namespace.def.general]") for N[.](#namespace-1.sentence-1)
For each non-friend redeclaration or specialization
whose target scope is or is contained by the scope,
the portion after the[*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1General[dcl.decl.general]"),[*class-head-name*](class.pre#nt:class-head-name "11.1Preamble[class.pre]"), or[*enum-head-name*](dcl.enum#nt:enum-head-name "9.8.1Enumeration declarations[dcl.enum]") is also included in the scope[.](#namespace-1.sentence-2)
The global scope is
the namespace scope of the global namespace ([[basic.namespace]](basic.namespace "9.9Namespaces"))[.](#namespace-1.sentence-3)
[*Example [1](#namespace-example-1)*: namespace Q {namespace V { void f(); }void V::f() { // in the scope of Vvoid h(); // declares Q::V::h}} — *end example*]
### [6.4.7](#class) Class scope [[basic.scope.class]](basic.scope.class)
[1](#class-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1528)
Any declaration of a class or class template C introduces
a [*class scope*](#def:scope,class "6.4.7Class scope[basic.scope.class]") that includes the [*member-specification*](class.mem.general#nt:member-specification "11.4.1General[class.mem.general]") of
the [*class-specifier*](class.pre#nt:class-specifier "11.1Preamble[class.pre]") for C (if any)[.](#class-1.sentence-1)
For each non-friend redeclaration or specialization
whose target scope is or is contained by the scope,
the portion after the[*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1General[dcl.decl.general]"),[*class-head-name*](class.pre#nt:class-head-name "11.1Preamble[class.pre]"), or[*enum-head-name*](dcl.enum#nt:enum-head-name "9.8.1Enumeration declarations[dcl.enum]") is also included in the scope[.](#class-1.sentence-2)
[*Note [1](#class-note-1)*:
Lookup from a program point
before the [*class-specifier*](class.pre#nt:class-specifier "11.1Preamble[class.pre]") of a class
will find no bindings in the class scope[.](#class-1.sentence-3)
[*Example [1](#class-example-1)*: template<class D>struct B { D::type x; // #1};
struct A { using type = int; };struct C : A, B<C> {}; // error at #1: C::type not found — *end example*]
— *end note*]
### [6.4.8](#enum) Enumeration scope [[basic.scope.enum]](basic.scope.enum)
[1](#enum-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1558)
Any declaration of an enumeration E introduces
an [*enumeration scope*](#def:scope,enumeration "6.4.8Enumeration scope[basic.scope.enum]") that includes the [*enumerator-list*](dcl.enum#nt:enumerator-list "9.8.1Enumeration declarations[dcl.enum]") of
the [*enum-specifier*](dcl.enum#nt:enum-specifier "9.8.1Enumeration declarations[dcl.enum]") for E (if any)[.](#enum-1.sentence-1)
### [6.4.9](#temp) Template parameter scope [[basic.scope.temp]](basic.scope.temp)
[1](#temp-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1566)
Each[*type-tt-parameter*](temp.param#nt:type-tt-parameter "13.2Template parameters[temp.param]"),[*variable-tt-parameter*](temp.param#nt:variable-tt-parameter "13.2Template parameters[temp.param]"), and[*concept-tt-parameter*](temp.param#nt:concept-tt-parameter "13.2Template parameters[temp.param]") introduces
a [*template parameter scope*](#def:scope,template_parameter "6.4.9Template parameter scope[basic.scope.temp]") that includes the [*template-head*](temp.pre#nt:template-head "13.1Preamble[temp.pre]") of
the [*template-parameter*](temp.param#nt:template-parameter "13.2Template parameters[temp.param]")[.](#temp-1.sentence-1)
[2](#temp-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1576)
Each [*template-declaration*](temp.pre#nt:template-declaration "13.1Preamble[temp.pre]") D introduces
a template parameter scope
that extends from the beginning of its [*template-parameter-list*](temp.pre#nt:template-parameter-list "13.1Preamble[temp.pre]") to the end of the [*template-declaration*](temp.pre#nt:template-declaration "13.1Preamble[temp.pre]")[.](#temp-2.sentence-1)
Any declaration outside the [*template-parameter-list*](temp.pre#nt:template-parameter-list "13.1Preamble[temp.pre]") that would inhabit that scope instead inhabits the same scope as D[.](#temp-2.sentence-2)
The parent scope of any scope S that is not a template parameter scope
is the smallest scope that contains S and is not a template parameter scope[.](#temp-2.sentence-3)
[*Note [1](#temp-note-1)*:
Therefore, only template parameters belong to a template parameter scope, and
only template parameter scopes have
a template parameter scope as a parent scope[.](#temp-2.sentence-4)
— *end note*]
### [6.4.10](#contract) Contract-assertion scope [[basic.scope.contract]](basic.scope.contract)
[1](#contract-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1593)
Each contract assertion ([[basic.contract]](basic.contract "6.11Contract assertions"))C introduces a [*contract-assertion scope*](#def:scope,contract-assertion "6.4.10Contract-assertion scope[basic.scope.contract]") that includes C[.](#contract-1.sentence-1)
[2](#contract-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1598)
If a [*result-name-introducer*](dcl.contract.res#nt:result-name-introducer "9.4.2Referring to the result object[dcl.contract.res]") ([[dcl.contract.res]](dcl.contract.res "9.4.2Referring to the result object"))
that is not name-independent ([[basic.scope.scope]](#scope "6.4.1General"))
and whose enclosing postcondition assertion
is associated with a function F potentially conflicts with
a declaration whose target scope is
- [(2.1)](#contract-2.1)
the function parameter scope of F or
- [(2.2)](#contract-2.2)
if associated with a [*lambda-declarator*](expr.prim.lambda.general#nt:lambda-declarator "7.5.6.1General[expr.prim.lambda.general]"),
the nearest enclosing lambda scope
of the precondition assertion ([[expr.prim.lambda]](expr.prim.lambda "7.5.6Lambda expressions")),
the program is ill-formed[.](#contract-2.sentence-1)

View File

@@ -0,0 +1,73 @@
[basic.scope.block]
# 6 Basics [[basic]](./#basic)
## 6.4 Scope [[basic.scope]](basic.scope#block)
### 6.4.3 Block scope [basic.scope.block]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1391)
Each
- [(1.1)](#1.1)
selection, iteration, or expansion statement ([[stmt.select]](stmt.select "8.5Selection statements"), [[stmt.iter]](stmt.iter "8.6Iteration statements"), [[stmt.expand]](stmt.expand "8.7Expansion statements")),
- [(1.2)](#1.2)
substatement of such a statement,
- [(1.3)](#1.3)
[*handler*](except.pre#nt:handler "14.1Preamble[except.pre]") ([[except.pre]](except.pre "14.1Preamble")), or
- [(1.4)](#1.4)
compound statement ([[stmt.block]](stmt.block "8.4Compound statement or block"))
that is not the [*compound-statement*](stmt.block#nt:compound-statement "8.4Compound statement or block[stmt.block]") of a [*handler*](except.pre#nt:handler "14.1Preamble[except.pre]")
introduces a [*block scope*](#def:scope,block "6.4.3Block scope[basic.scope.block]") that includes that statement or [*handler*](except.pre#nt:handler "14.1Preamble[except.pre]")[.](#1.sentence-1)
[*Note [1](#note-1)*:
A substatement that is also a block has only one scope[.](#1.sentence-2)
— *end note*]
A variable that belongs to a block scope is a [*block variable*](#def:block_variable "6.4.3Block scope[basic.scope.block]")[.](#1.sentence-3)
[*Example [1](#example-1)*: int i = 42;int a[10];
for (int i = 0; i < 10; i++) a[i] = i;
int j = i; // j = 42 — *end example*]
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1423)
If a declaration
that is not a name-independent declaration and
that binds a name in the block scope S of a
- [(2.1)](#2.1)
[*compound-statement*](stmt.block#nt:compound-statement "8.4Compound statement or block[stmt.block]") of a [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1General[expr.prim.lambda.general]"),[*function-body*](dcl.fct.def.general#nt:function-body "9.6.1General[dcl.fct.def.general]"), or [*function-try-block*](except.pre#nt:function-try-block "14.1Preamble[except.pre]"),
- [(2.2)](#2.2)
substatement of a selection or iteration statement
that is not itself a selection or iteration statement, or
- [(2.3)](#2.3)
[*handler*](except.pre#nt:handler "14.1Preamble[except.pre]") of a [*function-try-block*](except.pre#nt:function-try-block "14.1Preamble[except.pre]")
potentially conflicts with a declaration
whose target scope is the parent scope of S,
the program is ill-formed[.](#2.sentence-1)
[*Example [2](#example-2)*: if (int x = f()) {int x; // error: redeclaration of x}else {int x; // error: redeclaration of x} — *end example*]

View File

@@ -0,0 +1,31 @@
[basic.scope.class]
# 6 Basics [[basic]](./#basic)
## 6.4 Scope [[basic.scope]](basic.scope#class)
### 6.4.7 Class scope [basic.scope.class]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1528)
Any declaration of a class or class template C introduces
a [*class scope*](#def:scope,class "6.4.7Class scope[basic.scope.class]") that includes the [*member-specification*](class.mem.general#nt:member-specification "11.4.1General[class.mem.general]") of
the [*class-specifier*](class.pre#nt:class-specifier "11.1Preamble[class.pre]") for C (if any)[.](#1.sentence-1)
For each non-friend redeclaration or specialization
whose target scope is or is contained by the scope,
the portion after the[*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1General[dcl.decl.general]"),[*class-head-name*](class.pre#nt:class-head-name "11.1Preamble[class.pre]"), or[*enum-head-name*](dcl.enum#nt:enum-head-name "9.8.1Enumeration declarations[dcl.enum]") is also included in the scope[.](#1.sentence-2)
[*Note [1](#note-1)*:
Lookup from a program point
before the [*class-specifier*](class.pre#nt:class-specifier "11.1Preamble[class.pre]") of a class
will find no bindings in the class scope[.](#1.sentence-3)
[*Example [1](#example-1)*: template<class D>struct B { D::type x; // #1};
struct A { using type = int; };struct C : A, B<C> {}; // error at #1: C::type not found — *end example*]
— *end note*]

View File

@@ -0,0 +1,35 @@
[basic.scope.contract]
# 6 Basics [[basic]](./#basic)
## 6.4 Scope [[basic.scope]](basic.scope#contract)
### 6.4.10 Contract-assertion scope [basic.scope.contract]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1593)
Each contract assertion ([[basic.contract]](basic.contract "6.11Contract assertions"))C introduces a [*contract-assertion scope*](#def:scope,contract-assertion "6.4.10Contract-assertion scope[basic.scope.contract]") that includes C[.](#1.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1598)
If a [*result-name-introducer*](dcl.contract.res#nt:result-name-introducer "9.4.2Referring to the result object[dcl.contract.res]") ([[dcl.contract.res]](dcl.contract.res "9.4.2Referring to the result object"))
that is not name-independent ([[basic.scope.scope]](basic.scope.scope "6.4.1General"))
and whose enclosing postcondition assertion
is associated with a function F potentially conflicts with
a declaration whose target scope is
- [(2.1)](#2.1)
the function parameter scope of F or
- [(2.2)](#2.2)
if associated with a [*lambda-declarator*](expr.prim.lambda.general#nt:lambda-declarator "7.5.6.1General[expr.prim.lambda.general]"),
the nearest enclosing lambda scope
of the precondition assertion ([[expr.prim.lambda]](expr.prim.lambda "7.5.6Lambda expressions")),
the program is ill-formed[.](#2.sentence-1)

View File

@@ -0,0 +1,15 @@
[basic.scope.enum]
# 6 Basics [[basic]](./#basic)
## 6.4 Scope [[basic.scope]](basic.scope#enum)
### 6.4.8 Enumeration scope [basic.scope.enum]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1558)
Any declaration of an enumeration E introduces
an [*enumeration scope*](#def:scope,enumeration "6.4.8Enumeration scope[basic.scope.enum]") that includes the [*enumerator-list*](dcl.enum#nt:enumerator-list "9.8.1Enumeration declarations[dcl.enum]") of
the [*enum-specifier*](dcl.enum#nt:enum-specifier "9.8.1Enumeration declarations[dcl.enum]") for E (if any)[.](#1.sentence-1)

View File

@@ -0,0 +1,9 @@
[basic.scope.lambda]
# 6 Basics [[basic]](./#basic)
## 6.4 Scope [[basic.scope]](basic.scope#lambda)
### 6.4.5 Lambda scope [basic.scope.lambda]
A [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1General[expr.prim.lambda.general]") E introduces a [*lambda scope*](#def:scope,lambda "6.4.5Lambda scope[basic.scope.lambda]") that starts immediately after the [*lambda-introducer*](expr.prim.lambda.general#nt:lambda-introducer "7.5.6.1General[expr.prim.lambda.general]") of E and extends to the end of the [*compound-statement*](stmt.block#nt:compound-statement "8.4Compound statement or block[stmt.block]") of E[.](#sentence-1)

View File

@@ -0,0 +1,23 @@
[basic.scope.namespace]
# 6 Basics [[basic]](./#basic)
## 6.4 Scope [[basic.scope]](basic.scope#namespace)
### 6.4.6 Namespace scope [basic.scope.namespace]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1501)
Any [*namespace-definition*](namespace.def.general#nt:namespace-definition "9.9.2.1General[namespace.def.general]") for a namespace N introduces
a [*namespace scope*](#def:scope,namespace "6.4.6Namespace scope[basic.scope.namespace]") that includes the [*namespace-body*](namespace.def.general#nt:namespace-body "9.9.2.1General[namespace.def.general]") for every [*namespace-definition*](namespace.def.general#nt:namespace-definition "9.9.2.1General[namespace.def.general]") for N[.](#1.sentence-1)
For each non-friend redeclaration or specialization
whose target scope is or is contained by the scope,
the portion after the[*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1General[dcl.decl.general]"),[*class-head-name*](class.pre#nt:class-head-name "11.1Preamble[class.pre]"), or[*enum-head-name*](dcl.enum#nt:enum-head-name "9.8.1Enumeration declarations[dcl.enum]") is also included in the scope[.](#1.sentence-2)
The global scope is
the namespace scope of the global namespace ([[basic.namespace]](basic.namespace "9.9Namespaces"))[.](#1.sentence-3)
[*Example [1](#example-1)*: namespace Q {namespace V { void f(); }void V::f() { // in the scope of Vvoid h(); // declares Q::V::h}} — *end example*]

View File

@@ -0,0 +1,50 @@
[basic.scope.param]
# 6 Basics [[basic]](./#basic)
## 6.4 Scope [[basic.scope]](basic.scope#param)
### 6.4.4 Function parameter scope [basic.scope.param]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1456)
A [*parameter-declaration-clause*](dcl.fct#nt:parameter-declaration-clause "9.3.4.6Functions[dcl.fct]") P introduces
a [*function parameter scope*](#def:scope,function_parameter "6.4.4Function parameter scope[basic.scope.param]") that includes P[.](#1.sentence-1)
[*Note [1](#note-1)*:
A function parameter cannot be used for its value
within the [*parameter-declaration-clause*](dcl.fct#nt:parameter-declaration-clause "9.3.4.6Functions[dcl.fct]") ([[dcl.fct.default]](dcl.fct.default "9.3.4.7Default arguments"))[.](#1.sentence-2)
— *end note*]
- [(1.1)](#1.1)
If P is associated with a [*declarator*](dcl.decl.general#nt:declarator "9.3.1General[dcl.decl.general]") and
is preceded by a (possibly-parenthesized) [*noptr-declarator*](dcl.decl.general#nt:noptr-declarator "9.3.1General[dcl.decl.general]") of
the form[*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1General[dcl.decl.general]") [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")opt,
its scope extends to the end of the nearest enclosing[*init-declarator*](dcl.decl.general#nt:init-declarator "9.3.1General[dcl.decl.general]"),[*member-declarator*](class.mem.general#nt:member-declarator "11.4.1General[class.mem.general]"),[*declarator*](dcl.decl.general#nt:declarator "9.3.1General[dcl.decl.general]") of a [*parameter-declaration*](dcl.fct#nt:parameter-declaration "9.3.4.6Functions[dcl.fct]") or
a [*nodeclspec-function-declaration*](dcl.pre#nt:nodeclspec-function-declaration "9.1Preamble[dcl.pre]"), or[*function-definition*](dcl.fct.def.general#nt:function-definition "9.6.1General[dcl.fct.def.general]"),
but does not include the locus of the associated [*declarator*](dcl.decl.general#nt:declarator "9.3.1General[dcl.decl.general]")[.](#1.1.sentence-1)
[*Note [2](#note-2)*:
In this case, P declares the parameters of a function
(or a function or template parameter declared with function type)[.](#1.1.sentence-2)
A member function's parameter scope is nested within its class's scope[.](#1.1.sentence-3)
— *end note*]
- [(1.2)](#1.2)
If P is associated with a [*lambda-declarator*](expr.prim.lambda.general#nt:lambda-declarator "7.5.6.1General[expr.prim.lambda.general]"),
its scope extends to the end of the [*compound-statement*](stmt.block#nt:compound-statement "8.4Compound statement or block[stmt.block]") in the [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1General[expr.prim.lambda.general]")[.](#1.2.sentence-1)
- [(1.3)](#1.3)
If P is associated with a [*requirement-parameter-list*](expr.prim.req.general#nt:requirement-parameter-list "7.5.8.1General[expr.prim.req.general]"),
its scope extends to the end of the [*requirement-body*](expr.prim.req.general#nt:requirement-body "7.5.8.1General[expr.prim.req.general]") of the [*requires-expression*](expr.prim.req.general#nt:requires-expression "7.5.8.1General[expr.prim.req.general]")[.](#1.3.sentence-1)
- [(1.4)](#1.4)
If P is associated with a [*deduction-guide*](temp.deduct.guide#nt:deduction-guide "13.7.2.3Deduction guides[temp.deduct.guide]"),
its scope extends to the end of the [*deduction-guide*](temp.deduct.guide#nt:deduction-guide "13.7.2.3Deduction guides[temp.deduct.guide]")[.](#1.4.sentence-1)

View File

@@ -0,0 +1,195 @@
[basic.scope.pdecl]
# 6 Basics [[basic]](./#basic)
## 6.4 Scope [[basic.scope]](basic.scope#pdecl)
### 6.4.2 Point of declaration [basic.scope.pdecl]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1237)
The [*locus*](#def:locus "6.4.2Point of declaration[basic.scope.pdecl]") of a declaration ([[basic.pre]](basic.pre "6.1Preamble")) that is a declarator
is immediately after the complete declarator ([[dcl.decl]](dcl.decl "9.3Declarators"))[.](#1.sentence-1)
[*Example [1](#example-1)*: unsigned char x = 12;{ unsigned char x = x; }
Here, the initialization of the second x has undefined behavior,
because the initializer accesses the second x outside its lifetime ([[basic.life]](basic.life "6.8.4Lifetime"))[.](#1.sentence-2)
— *end example*]
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1251)
[*Note [1](#note-1)*:
A name from an outer scope remains visible up to
the locus of the declaration that hides it[.](#2.sentence-1)
[*Example [2](#example-2)*:
const int i = 2;{ int i[i]; } declares a block-scope array of two integers[.](#2.sentence-2)
— *end example*]
— *end note*]
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1265)
The locus of a [*class-specifier*](class.pre#nt:class-specifier "11.1Preamble[class.pre]") is immediately after
the [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") or [*simple-template-id*](temp.names#nt:simple-template-id "13.3Names of template specializations[temp.names]") (if any)
in its [*class-head*](class.pre#nt:class-head "11.1Preamble[class.pre]") ([[class.pre]](class.pre "11.1Preamble"))[.](#3.sentence-1)
The locus of an [*enum-specifier*](dcl.enum#nt:enum-specifier "9.8.1Enumeration declarations[dcl.enum]") is immediately after
its [*enum-head*](dcl.enum#nt:enum-head "9.8.1Enumeration declarations[dcl.enum]");
the locus of an [*opaque-enum-declaration*](dcl.enum#nt:opaque-enum-declaration "9.8.1Enumeration declarations[dcl.enum]") is immediately after it ([[dcl.enum]](dcl.enum "9.8.1Enumeration declarations"))[.](#3.sentence-2)
The locus of an [*alias-declaration*](dcl.pre#nt:alias-declaration "9.1Preamble[dcl.pre]") is immediately after it[.](#3.sentence-3)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1277)
The locus of a [*using-declarator*](namespace.udecl#nt:using-declarator "9.10The using declaration[namespace.udecl]") that does not name a constructor
is immediately after the [*using-declarator*](namespace.udecl#nt:using-declarator "9.10The using declaration[namespace.udecl]") ([[namespace.udecl]](namespace.udecl "9.10The using declaration"))[.](#4.sentence-1)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1282)
The locus of an [*enumerator-definition*](dcl.enum#nt:enumerator-definition "9.8.1Enumeration declarations[dcl.enum]") is immediately after it[.](#5.sentence-1)
[*Example [3](#example-3)*: const int x = 12;{ enum { x = x }; }
Here, the enumerator x is initialized with the value of the
constant x, namely 12[.](#5.sentence-2)
— *end example*]
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1293)
[*Note [2](#note-2)*:
After the declaration of a class member,
the member name can be found in the scope of its class
even if the class is an incomplete class[.](#6.sentence-1)
[*Example [4](#example-4)*: struct X {enum E { z = 16 }; int b[X::z]; // OK}; — *end example*]
— *end note*]
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1309)
The locus of an [*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5Elaborated type specifiers[dcl.type.elab]") that is a declaration ([[dcl.type.elab]](dcl.type.elab "9.2.9.5Elaborated type specifiers")) is immediately after it[.](#7.sentence-1)
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1313)
The locus of an injected-class-name declaration ([[class.pre]](class.pre "11.1Preamble"))
is immediately following the opening brace of the class definition[.](#8.sentence-1)
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1317)
The locus of the implicit declaration of
a function-local predefined variable ([[dcl.fct.def.general]](dcl.fct.def.general "9.6.1General"))
is immediately before
the [*function-body*](dcl.fct.def.general#nt:function-body "9.6.1General[dcl.fct.def.general]") of its function's definition[.](#9.sentence-1)
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1323)
The locus of the declaration of a structured binding ([[dcl.struct.bind]](dcl.struct.bind "9.7Structured binding declarations"))
is immediately after
the [*identifier-list*](cpp.pre#nt:identifier-list "15.1Preamble[cpp.pre]") of the structured binding declaration[.](#10.sentence-1)
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1328)
The locus of a [*for-range-declaration*](stmt.pre#nt:for-range-declaration "8.1Preamble[stmt.pre]") of a range-based for statement ([[stmt.ranged]](stmt.ranged "8.6.5The range-based for statement"))
is immediately after the [*for-range-initializer*](stmt.pre#nt:for-range-initializer "8.1Preamble[stmt.pre]")[.](#11.sentence-1)
The locus of a [*for-range-declaration*](stmt.pre#nt:for-range-declaration "8.1Preamble[stmt.pre]") of an expansion statement ([[stmt.expand]](stmt.expand "8.7Expansion statements"))
is immediately after the [*expansion-initializer*](stmt.expand#nt:expansion-initializer "8.7Expansion statements[stmt.expand]")[.](#11.sentence-2)
[12](#12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1336)
The locus of a [*template-parameter*](temp.param#nt:template-parameter "13.2Template parameters[temp.param]") is immediately after it[.](#12.sentence-1)
[*Example [5](#example-5)*: typedef unsigned char T;template<class T = T // lookup finds the [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4The typedef specifier[dcl.typedef]") , T // lookup finds the template parameter N = 0> struct A { }; — *end example*]
[13](#13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1348)
The locus of a [*result-name-introducer*](dcl.contract.res#nt:result-name-introducer "9.4.2Referring to the result object[dcl.contract.res]") ([[dcl.contract.res]](dcl.contract.res "9.4.2Referring to the result object"))
is immediately after it[.](#13.sentence-1)
[14](#14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1352)
The locus of a [*concept-definition*](temp.concept#nt:concept-definition "13.7.9Concept definitions[temp.concept]") is immediately after its [*concept-name*](temp.concept#nt:concept-name "13.7.9Concept definitions[temp.concept]") ([[temp.concept]](temp.concept "13.7.9Concept definitions"))[.](#14.sentence-1)
[*Note [3](#note-3)*:
The [*constraint-expression*](temp.constr.decl#nt:constraint-expression "13.5.3Constrained declarations[temp.constr.decl]") cannot use
the [*concept-name*](temp.concept#nt:concept-name "13.7.9Concept definitions[temp.concept]")[.](#14.sentence-2)
— *end note*]
[15](#15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1360)
The locus of a [*namespace-definition*](namespace.def.general#nt:namespace-definition "9.9.2.1General[namespace.def.general]") with an [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") is immediately after the [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]")[.](#15.sentence-1)
[*Note [4](#note-4)*:
An identifier is invented
for an [*unnamed-namespace-definition*](namespace.def.general#nt:unnamed-namespace-definition "9.9.2.1General[namespace.def.general]") ([[namespace.unnamed]](namespace.unnamed "9.9.2.2Unnamed namespaces"))[.](#15.sentence-2)
— *end note*]
[16](#16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1369)
[*Note [5](#note-5)*:
Friend declarations can introduce functions or classes
that belong to the nearest enclosing namespace or block scope,
but they do not bind names anywhere ([[class.friend]](class.friend "11.8.4Friends"))[.](#16.sentence-1)
Function declarations at block scope and
variable declarations with the extern specifier at block scope
declare entities
that belong to the nearest enclosing namespace,
but they do not bind names in it[.](#16.sentence-2)
— *end note*]
[17](#17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1381)
[*Note [6](#note-6)*:
For point of instantiation of a template, see [[temp.point]](temp.point "13.8.4.1Point of instantiation")[.](#17.sentence-1)
— *end note*]

View File

@@ -0,0 +1,289 @@
[basic.scope.scope]
# 6 Basics [[basic]](./#basic)
## 6.4 Scope [[basic.scope]](basic.scope#scope)
### 6.4.1 General [basic.scope.scope]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L939)
The declarations in a program appear in a number of [*scopes*](#def:scope "6.4.1General[basic.scope.scope]") that are in general discontiguous[.](#1.sentence-1)
The [*global scope*](#def:scope,global "6.4.1General[basic.scope.scope]") contains the entire program;
every other scope S is introduced by a
declaration,[*parameter-declaration-clause*](dcl.fct#nt:parameter-declaration-clause "9.3.4.6Functions[dcl.fct]"),[*statement*](stmt.pre#nt:statement "8.1Preamble[stmt.pre]"),[*handler*](except.pre#nt:handler "14.1Preamble[except.pre]"), or
contract assertion
(as described in the following subclauses of [[basic.scope]](basic.scope "6.4Scope"))
appearing in another scope, which thereby contains S[.](#1.sentence-2)
An [*enclosing scope*](#def:scope,enclosing "6.4.1General[basic.scope.scope]") at a program point is any scope that contains it;
the smallest such scope is said to be the [*immediate scope*](#def:scope,immediate "6.4.1General[basic.scope.scope]") at that point[.](#1.sentence-3)
A scope [*intervenes*](#def:scope,intervene "6.4.1General[basic.scope.scope]") between a program point P and a scope S (that does not contain P) if it is or contains S but does not contain P[.](#1.sentence-4)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L958)
Unless otherwise specified:
- [(2.1)](#2.1)
The smallest scope that contains a scope S is
the [*parent scope*](#def:scope,parent "6.4.1General[basic.scope.scope]") of S[.](#2.1.sentence-1)
- [(2.2)](#2.2)
No two declarations (re)introduce the same entity[.](#2.2.sentence-1)
- [(2.3)](#2.3)
A declaration [*inhabits*](#def:scope,inhabit "6.4.1General[basic.scope.scope]") the immediate scope at its locus ([[basic.scope.pdecl]](basic.scope.pdecl "6.4.2Point of declaration"))[.](#2.3.sentence-1)
- [(2.4)](#2.4)
A declaration's [*target scope*](#def:scope,target "6.4.1General[basic.scope.scope]") is the scope it inhabits[.](#2.4.sentence-1)
- [(2.5)](#2.5)
Any names (re)introduced by a declaration are [*bound*](#def:name,bound "6.4.1General[basic.scope.scope]") to it
in its target scope[.](#2.5.sentence-1)
The [*host scope*](#def:scope,host "6.4.1General[basic.scope.scope]") of a declaration is
the inhabited scope if that scope is a block scope and
the target scope otherwise[.](#2.sentence-2)
An entity [*belongs*](#def:entity,belong "6.4.1General[basic.scope.scope]") to a scope S if S is the target scope of a declaration of the entity[.](#2.sentence-3)
[*Note [1](#note-1)*:
Special cases include that:
- [(2.6)](#2.6)
Template parameter scopes are parents
only to other template parameter scopes ([[basic.scope.temp]](basic.scope.temp "6.4.9Template parameter scope"))[.](#2.6.sentence-1)
- [(2.7)](#2.7)
Corresponding declarations with appropriate linkage
declare the same entity ([[basic.link]](basic.link "6.7Program and linkage"))[.](#2.7.sentence-1)
- [(2.8)](#2.8)
The declaration in a [*template-declaration*](temp.pre#nt:template-declaration "13.1Preamble[temp.pre]") inhabits the same scope as the [*template-declaration*](temp.pre#nt:template-declaration "13.1Preamble[temp.pre]")[.](#2.8.sentence-1)
- [(2.9)](#2.9)
Friend declarations and
declarations of template specializations do not bind names ([[dcl.meaning]](dcl.meaning "9.3.4Meaning of declarators"));
those with qualified names target a specified scope, and
other friend declarations and
certain [*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5Elaborated type specifiers[dcl.type.elab]")*s* ([[dcl.type.elab]](dcl.type.elab "9.2.9.5Elaborated type specifiers"))
target a larger enclosing scope[.](#2.9.sentence-1)
- [(2.10)](#2.10)
Block-scope extern or function declarations target a larger enclosing scope
but bind a name in their immediate scope ([[dcl.meaning.general]](dcl.meaning.general "9.3.4.1General"))[.](#2.10.sentence-1)
- [(2.11)](#2.11)
The names of unscoped enumerators are bound
in the two innermost enclosing scopes ([[dcl.enum]](dcl.enum "9.8.1Enumeration declarations"))[.](#2.11.sentence-1)
- [(2.12)](#2.12)
A class's name is also bound in its own scope ([[class.pre]](class.pre "11.1Preamble"))[.](#2.12.sentence-1)
- [(2.13)](#2.13)
The names of the members of an anonymous union are bound in
the union's parent scope ([[class.union.anon]](class.union.anon "11.5.2Anonymous unions"))[.](#2.13.sentence-1)
— *end note*]
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1013)
Two non-static member functions have[*corresponding object parameters*](#def:object_parameter,corresponding "6.4.1General[basic.scope.scope]") if
- [(3.1)](#3.1)
exactly one is an implicit object member function
with no [*ref-qualifier*](dcl.decl.general#nt:ref-qualifier "9.3.1General[dcl.decl.general]") and
the types of their object parameters ([[dcl.fct]](dcl.fct "9.3.4.6Functions")),
after removing references,
are the same, or
- [(3.2)](#3.2)
their object parameters have the same type[.](#3.sentence-1)
Two non-static member function templates have[*corresponding object parameters*](#def:object_parameter,corresponding "6.4.1General[basic.scope.scope]") if
- [(3.3)](#3.3)
exactly one is an implicit object member function
with no [*ref-qualifier*](dcl.decl.general#nt:ref-qualifier "9.3.1General[dcl.decl.general]") and
the types of their object parameters,
after removing any references,
are equivalent, or
- [(3.4)](#3.4)
the types of their object parameters are equivalent[.](#3.sentence-2)
Two function templates have[*corresponding signatures*](#def:signature,corresponding "6.4.1General[basic.scope.scope]") if
their [*template-parameter-list*](temp.pre#nt:template-parameter-list "13.1Preamble[temp.pre]")*s* have the same length,
their corresponding [*template-parameter*](temp.param#nt:template-parameter "13.2Template parameters[temp.param]")*s* are equivalent,
they have equivalent non-object-parameter-type-lists and return types (if any), and,
if both are non-static members, they have corresponding object parameters[.](#3.sentence-3)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1048)
Two declarations [*correspond*](#def:correspond "6.4.1General[basic.scope.scope]") if they (re)introduce the same name,
both declare constructors, or
both declare destructors,
unless
- [(4.1)](#4.1)
either is a [*using-declarator*](namespace.udecl#nt:using-declarator "9.10The using declaration[namespace.udecl]"), or
- [(4.2)](#4.2)
one declares a type (not a type alias) and the other declares a
variable,
non-static data member other than of an anonymous union ([[class.union.anon]](class.union.anon "11.5.2Anonymous unions")),
enumerator,
function, or
function template, or
- [(4.3)](#4.3)
each declares a function or function template
and they do not declare corresponding overloads[.](#4.sentence-1)
Two function or function template declarations declare[*corresponding overloads*](#def:corresponding_overloads "6.4.1General[basic.scope.scope]") if
- [(4.4)](#4.4)
both declare functions with the same non-object-parameter-type-list,[17](#footnote-17 "An implicit object parameter ([over.match.funcs]) is not part of the parameter-type-list.") equivalent ([[temp.over.link]](temp.over.link "13.7.7.2Function template overloading")) trailing [*requires-clause*](temp.pre#nt:requires-clause "13.1Preamble[temp.pre]")*s* (if any, except as specified in [[temp.friend]](temp.friend "13.7.5Friends")), and,
if both are non-static members,
they have corresponding object parameters, or
- [(4.5)](#4.5)
both declare function templates with corresponding signatures and equivalent[*template-head*](temp.pre#nt:template-head "13.1Preamble[temp.pre]")*s* and
trailing [*requires-clause*](temp.pre#nt:requires-clause "13.1Preamble[temp.pre]")*s* (if any)[.](#4.sentence-2)
[*Note [2](#note-2)*:
Declarations can correspond even if neither binds a name[.](#4.sentence-3)
[*Example [1](#example-1)*: struct A {friend void f(); // #1};struct B {friend void f() {} // corresponds to, and defines, #1}; — *end example*]
— *end note*]
[*Example [2](#example-2)*: typedef int Int;enum E : int { a };void f(int); // #1void f(Int) {} // defines #1void f(E) {} // OK, another overloadstruct X {static void f(); void f() const; // error: redeclarationvoid g(); void g() const; // OKvoid g() &; // error: redeclarationvoid h(this X&, int); void h(int) &&; // OK, another overloadvoid j(this const X&); void j() const &; // error: redeclarationvoid k(); void k(this X&); // error: redeclaration}; — *end example*]
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1124)
A declaration is [*name-independent*](#def:declaration,name-independent "6.4.1General[basic.scope.scope]") if its name is _ (U+005f low line) and it declares
- [(5.1)](#5.1)
a variable with automatic storage duration,
- [(5.2)](#5.2)
a structured binding
with no [*storage-class-specifier*](dcl.stc#nt:storage-class-specifier "9.2.2Storage class specifiers[dcl.stc]") and
not inhabiting a namespace scope,
- [(5.3)](#5.3)
a result binding ([[dcl.contract.res]](dcl.contract.res "9.4.2Referring to the result object")),
- [(5.4)](#5.4)
the variable introduced by an [*init-capture*](expr.prim.lambda.capture#nt:init-capture "7.5.6.3Captures[expr.prim.lambda.capture]"), or
- [(5.5)](#5.5)
a non-static data member of other than an anonymous union[.](#5.sentence-1)
*Recommended practice*: Implementations should not emit a warning
that a name-independent declaration is used or unused[.](#5.sentence-2)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1150)
Two declarations [*potentially conflict*](#def:potentially_conflict "6.4.1General[basic.scope.scope]") if they correspond and
cause their shared name to denote different entities ([[basic.link]](basic.link "6.7Program and linkage"))[.](#6.sentence-1)
The program is ill-formed
if, in any scope, a name is bound to two declarations A and B that potentially conflict and A precedes B ([[basic.lookup]](basic.lookup "6.5Name lookup")),
unless B is name-independent[.](#6.sentence-2)
[*Note [3](#note-3)*:
An [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1General[expr.prim.id.general]") that names a unique name-independent declaration
is usable until an additional declaration of the same name
is introduced in the same scope ([[basic.lookup.general]](basic.lookup.general "6.5.1General"))[.](#6.sentence-3)
— *end note*]
[*Note [4](#note-4)*:
Overload resolution can consider potentially conflicting declarations
found in multiple scopes
(e.g., via [*using-directive*](namespace.udir#nt:using-directive "9.9.4Using namespace directive[namespace.udir]")*s* or for operator functions),
in which case it is often ambiguous[.](#6.sentence-4)
— *end note*]
[*Example [3](#example-3)*: void f() {int x,y; void x(); // error: different entity for xint y; // error: redefinition}enum { f }; // error: different entity for ::fnamespace A {}namespace B = A;namespace B = A; // OK, no effectnamespace B = B; // OK, no effectnamespace A = B; // OK, no effectnamespace B {} // error: different entity for Bvoid g() {int _;
_ = 0; // OKint _; // OK, name-independent declaration _ = 0; // error: two non-function declarations in the lookup set}void h () {int _; // #1 _ ++; // OKstatic int _; // error: conflicts with #1 because static variables are not name-independent} — *end example*]
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1199)
A declaration is [*nominable*](#def:nominable "6.4.1General[basic.scope.scope]") in a class, class template, or namespace E at a point P if
it precedes P,
it does not inhabit a block scope, and
its target scope is the scope associated with E or,
if E is a namespace,
any element of the inline namespace set of E ([[namespace.def]](namespace.def "9.9.2Namespace definition"))[.](#7.sentence-1)
[*Example [4](#example-4)*: namespace A {void f() {void g();}inline namespace B {struct S {friend void h(); static int i; }; }}
At the end of this example,
the declarations of f, B, S, and h are nominable in A, but those of g and i are not[.](#7.sentence-2)
— *end example*]
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1225)
When instantiating a templated entity ([[temp.pre]](temp.pre "13.1Preamble")),
any scope S introduced by any part of the template definition is considered
to be introduced by the instantiated entity and
to contain the instantiations of any declarations that inhabit S[.](#8.sentence-1)
[17)](#footnote-17)[17)](#footnoteref-17)
An implicit object parameter ([[over.match.funcs]](over.match.funcs "12.2.2Candidate functions and argument lists"))
is not part of the parameter-type-list[.](#footnote-17.sentence-1)

View File

@@ -0,0 +1,36 @@
[basic.scope.temp]
# 6 Basics [[basic]](./#basic)
## 6.4 Scope [[basic.scope]](basic.scope#temp)
### 6.4.9 Template parameter scope [basic.scope.temp]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1566)
Each[*type-tt-parameter*](temp.param#nt:type-tt-parameter "13.2Template parameters[temp.param]"),[*variable-tt-parameter*](temp.param#nt:variable-tt-parameter "13.2Template parameters[temp.param]"), and[*concept-tt-parameter*](temp.param#nt:concept-tt-parameter "13.2Template parameters[temp.param]") introduces
a [*template parameter scope*](#def:scope,template_parameter "6.4.9Template parameter scope[basic.scope.temp]") that includes the [*template-head*](temp.pre#nt:template-head "13.1Preamble[temp.pre]") of
the [*template-parameter*](temp.param#nt:template-parameter "13.2Template parameters[temp.param]")[.](#1.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1576)
Each [*template-declaration*](temp.pre#nt:template-declaration "13.1Preamble[temp.pre]") D introduces
a template parameter scope
that extends from the beginning of its [*template-parameter-list*](temp.pre#nt:template-parameter-list "13.1Preamble[temp.pre]") to the end of the [*template-declaration*](temp.pre#nt:template-declaration "13.1Preamble[temp.pre]")[.](#2.sentence-1)
Any declaration outside the [*template-parameter-list*](temp.pre#nt:template-parameter-list "13.1Preamble[temp.pre]") that would inhabit that scope instead inhabits the same scope as D[.](#2.sentence-2)
The parent scope of any scope S that is not a template parameter scope
is the smallest scope that contains S and is not a template parameter scope[.](#2.sentence-3)
[*Note [1](#note-1)*:
Therefore, only template parameters belong to a template parameter scope, and
only template parameter scopes have
a template parameter scope as a parent scope[.](#2.sentence-4)
— *end note*]

63
cppdraft/basic/splice.md Normal file
View File

@@ -0,0 +1,63 @@
[basic.splice]
# 6 Basics [[basic]](./#basic)
## 6.6 Splice specifiers [basic.splice]
[splice-specifier:](#nt:splice-specifier "6.6Splice specifiers[basic.splice]")
[: [*constant-expression*](expr.const#nt:constant-expression "7.7Constant expressions[expr.const]") :]
[splice-specialization-specifier:](#nt:splice-specialization-specifier "6.6Splice specifiers[basic.splice]")
[*splice-specifier*](#nt:splice-specifier "6.6Splice specifiers[basic.splice]") < [*template-argument-list*](temp.names#nt:template-argument-list "13.3Names of template specializations[temp.names]")opt >
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2822)
The [*constant-expression*](expr.const#nt:constant-expression "7.7Constant expressions[expr.const]") of a [*splice-specifier*](#nt:splice-specifier "6.6Splice specifiers[basic.splice]") shall be a converted constant expression of
type std::meta::info ([[expr.const]](expr.const "7.7Constant expressions"))[.](#1.sentence-1)
A [*splice-specifier*](#nt:splice-specifier "6.6Splice specifiers[basic.splice]") whose converted [*constant-expression*](expr.const#nt:constant-expression "7.7Constant expressions[expr.const]") represents
a construct X is said to [*designate*](#def:designate "6.6Splice specifiers[basic.splice]") either
- [(1.1)](#1.1)
the underlying entity of X if X is an entity ([[basic.pre]](basic.pre "6.1Preamble")), or
- [(1.2)](#1.2)
X otherwise[.](#1.sentence-2)
[*Note [1](#note-1)*:
A [*splice-specifier*](#nt:splice-specifier "6.6Splice specifiers[basic.splice]") is dependent
if the converted [*constant-expression*](expr.const#nt:constant-expression "7.7Constant expressions[expr.const]") is
value-dependent ([[temp.dep.splice]](temp.dep.splice "13.8.3.5Dependent splice specifiers"))[.](#1.sentence-3)
— *end note*]
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2839)
A non-dependent [*splice-specifier*](#nt:splice-specifier "6.6Splice specifiers[basic.splice]") of
a [*splice-specialization-specifier*](#nt:splice-specialization-specifier "6.6Splice specifiers[basic.splice]") shall designate a template[.](#2.sentence-1)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2843)
[*Note [2](#note-2)*:
A < following a [*splice-specifier*](#nt:splice-specifier "6.6Splice specifiers[basic.splice]") is interpreted as
the delimiter of a [*template-argument-list*](temp.names#nt:template-argument-list "13.3Names of template specializations[temp.names]") when the [*splice-specifier*](#nt:splice-specifier "6.6Splice specifiers[basic.splice]") is preceded by
the keyword template or the keyword typename, or
when it appears in a type-only context ([[temp.names]](temp.names "13.3Names of template specializations"))[.](#3.sentence-1)
[*Example [1](#example-1)*: constexpr int v = 1;template<int V> struct TCls {static constexpr int s = V + 1;};
using alias = [:^^TCls:]<([:^^v:])>; // OK, a [*splice-specialization-specifier*](#nt:splice-specialization-specifier "6.6Splice specifiers[basic.splice]") with a parenthesized [*splice-expression*](expr.prim.splice#nt:splice-expression "7.5.9Expression splicing[expr.prim.splice]") as a template argumentstatic_assert(alias::s == 2);
auto o1 = [:^^TCls:]<([:^^v:])>(); // error: < means less thanauto o2 = typename [:^^TCls:]<([:^^v:])>(); // OK, o2 is an object of type TCls<1>consteval int bad_splice(std::meta::info v) {return [:v:]; // error: v is not constant} — *end example*]
— *end note*]

515
cppdraft/basic/start.md Normal file
View File

@@ -0,0 +1,515 @@
[basic.start]
# 6 Basics [[basic]](./#basic)
## 6.10 Program execution [[basic.exec]](basic.exec#basic.start)
### 6.10.3 Start and termination [basic.start]
#### [6.10.3.1](#main) main function [[basic.start.main]](basic.start.main)
[1](#main-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7129)
A program shall contain exactly one function called main that belongs to the global scope[.](#main-1.sentence-1)
Executing a program starts a main thread of execution ([[intro.multithread]](intro.multithread "6.10.2Multi-threaded executions and data races"), [[thread.threads]](thread.threads "32.4Threads"))
in which the main function is invoked[.](#main-1.sentence-2)
It is implementation-defined
whether a program in a freestanding environment is required to define a main function[.](#main-1.sentence-3)
[*Note [1](#main-note-1)*:
In a freestanding environment, startup and termination isimplementation-defined; startup contains the
execution of constructors for non-local objects with static storage duration;
termination contains the execution of destructors for objects with static storage
duration[.](#main-1.sentence-4)
— *end note*]
[2](#main-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7147)
An implementation shall not predefine the main function[.](#main-2.sentence-1)
Its type shall have C++ language linkage
and it shall have a declared return type of typeint, but otherwise its type is implementation-defined[.](#main-2.sentence-2)
An implementation shall allow both
- [(2.1)](#main-2.1)
a function of () returning int and
- [(2.2)](#main-2.2)
a function of (int, pointer to pointer to char) returning int
as the type of main ([[dcl.fct]](dcl.fct "9.3.4.6Functions"))[.](#main-2.sentence-3)
In the latter form, for purposes of exposition, the first function
parameter is called argc and the second function parameter is
called argv, where argc shall be the number of
arguments passed to the program from the environment in which the
program is run[.](#main-2.sentence-4)
Ifargc is nonzero these arguments shall be supplied inargv[0] through argv[argc - 1] as pointers to the initial
characters of null-terminated multibyte strings (ntmbss) ([[multibyte.strings]](multibyte.strings "16.3.3.3.4.3Multibyte strings"))
and argv[0] shall be the pointer to
the initial character of an ntmbs that represents the name used to
invoke the program or ""[.](#main-2.sentence-5)
The value of argc shall be
non-negative[.](#main-2.sentence-6)
The value of argv[argc] shall be 0[.](#main-2.sentence-7)
*Recommended practice*: Any further (optional) parameters should be added after argv[.](#main-2.sentence-8)
[3](#main-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7179)
The function main shall not be named by an expression[.](#main-3.sentence-1)
The linkage ([[basic.link]](basic.link "6.7Program and linkage")) of main isimplementation-defined[.](#main-3.sentence-2)
A program that defines main as
deleted or that declares main to beinline, static, constexpr, or consteval is ill-formed[.](#main-3.sentence-3)
The function main shall not be a coroutine ([[dcl.fct.def.coroutine]](dcl.fct.def.coroutine "9.6.4Coroutine definitions"))[.](#main-3.sentence-4)
The main function shall not be declared with a[*linkage-specification*](dcl.link#nt:linkage-specification "9.12Linkage specifications[dcl.link]") ([[dcl.link]](dcl.link "9.12Linkage specifications")) other than "C++"[.](#main-3.sentence-5)
A program that declares
- [(3.1)](#main-3.1)
a variable main that belongs to the global scope, or
- [(3.2)](#main-3.2)
a function main that belongs to the global scope and
is attached to a named module, or
- [(3.3)](#main-3.3)
a function template main that belongs to the global scope, or
- [(3.4)](#main-3.4)
an entity named main with C language linkage (in any namespace)
is ill-formed[.](#main-3.sentence-6)
The name main is
not otherwise reserved[.](#main-3.sentence-7)
[*Example [1](#main-example-1)*:
Member functions, classes, and
enumerations can be called main, as can entities in other
namespaces[.](#main-3.sentence-8)
— *end example*]
[4](#main-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7211)
Terminating the program
without leaving the current block (e.g., by calling the functionstd::exit(int) ([[support.start.term]](support.start.term "17.5Startup and termination"))) does not destroy any
objects with automatic storage duration ([[class.dtor]](class.dtor "11.4.7Destructors"))[.](#main-4.sentence-1)
Ifstd::exit is invoked during the destruction of
an object with static or thread storage duration, the program has undefined
behavior[.](#main-4.sentence-2)
[5](#main-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7223)
A return statement ([[stmt.return]](stmt.return "8.8.4The return statement")) in main has the effect of leaving the main function (destroying any objects with automatic storage duration
and evaluating any postcondition assertions of main)
and calling std::exit with the return value as the argument[.](#main-5.sentence-1)
If control flows off the end of
the [*compound-statement*](stmt.block#nt:compound-statement "8.4Compound statement or block[stmt.block]") of main,
the effect is equivalent to a return with operand 0 (see also [[except.handle]](except.handle "14.4Handling an exception"))[.](#main-5.sentence-2)
#### [6.10.3.2](#static) Static initialization [[basic.start.static]](basic.start.static)
[1](#static-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7238)
Variables with static storage duration
are initialized as a consequence of program initiation[.](#static-1.sentence-1)
Variables with
thread storage duration are initialized as a consequence of thread execution[.](#static-1.sentence-2)
Within each of these phases of initiation, initialization occurs as follows[.](#static-1.sentence-3)
[2](#static-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7246)
[*Constant initialization*](#def:constant_initialization "6.10.3.2Static initialization[basic.start.static]") is performed
if a variable with static or thread storage duration
is constant-initialized ([[expr.const]](expr.const "7.7Constant expressions"))[.](#static-2.sentence-1)
If constant initialization is not performed, a variable with static
storage duration ([[basic.stc.static]](basic.stc.static "6.8.6.2Static storage duration")) or thread storage
duration ([[basic.stc.thread]](basic.stc.thread "6.8.6.3Thread storage duration")) is zero-initialized ([[dcl.init]](dcl.init "9.5Initializers"))[.](#static-2.sentence-2)
Together, zero-initialization and constant initialization are called[*static initialization*](#def:initialization,static "6.10.3.2Static initialization[basic.start.static]");
all other initialization is [*dynamic initialization*](#def:initialization,dynamic "6.10.3.2Static initialization[basic.start.static]")[.](#static-2.sentence-3)
All static initialization strongly happens before ([[intro.races]](intro.races "6.10.2.2Data races"))
any dynamic initialization[.](#static-2.sentence-4)
[*Note [1](#static-note-1)*:
The dynamic initialization of non-block variables is described
in [[basic.start.dynamic]](#dynamic "6.10.3.3Dynamic initialization of non-block variables"); that of static block variables is described
in [[stmt.dcl]](stmt.dcl "8.10Declaration statement")[.](#static-2.sentence-5)
— *end note*]
[3](#static-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7266)
An implementation is permitted to perform the initialization of a
variable with static or thread storage duration as a static
initialization even if such initialization is not required to be done
statically, provided that
- [(3.1)](#static-3.1)
the dynamic version of the initialization does not change the
value of any other object of static or thread storage duration
prior to its initialization, and
- [(3.2)](#static-3.2)
the static version of the initialization produces the same value
in the initialized variable as would be produced by the dynamic
initialization if all variables not required to be initialized statically
were initialized dynamically[.](#static-3.sentence-1)
[*Note [2](#static-note-2)*:
As a consequence, if the initialization of an object obj1 refers to an
object obj2 potentially requiring dynamic initialization and defined
later in the same translation unit, it is unspecified whether the value of obj2 used
will be the value of the fully initialized obj2 (because obj2 was statically
initialized) or will be the value of obj2 merely zero-initialized[.](#static-3.sentence-2)
For example,inline double fd() { return 1.0; }extern double d1;double d2 = d1; // unspecified:// either statically initialized to 0.0 or// dynamically initialized to 0.0 if d1 is// dynamically initialized, or 1.0 otherwisedouble d1 = fd(); // either initialized statically or dynamically to 1.0
— *end note*]
#### [6.10.3.3](#dynamic) Dynamic initialization of non-block variables [[basic.start.dynamic]](basic.start.dynamic)
[1](#dynamic-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7302)
Dynamic initialization of a non-block variable with static storage duration is
unordered if the variable is an implicitly or explicitly instantiated
specialization, is partially-ordered if the variable
is an inline variable that is not an implicitly or explicitly instantiated
specialization, and otherwise is ordered[.](#dynamic-1.sentence-1)
[*Note [1](#dynamic-note-1)*:
A non-inline explicit specialization of a templated variable
has ordered initialization[.](#dynamic-1.sentence-2)
— *end note*]
[2](#dynamic-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7316)
A declaration D is[*appearance-ordered*](#def:appearance-ordered "6.10.3.3Dynamic initialization of non-block variables[basic.start.dynamic]") before a declaration E if
- [(2.1)](#dynamic-2.1)
D appears in the same translation unit as E, or
- [(2.2)](#dynamic-2.2)
the translation unit containing E has an interface dependency on the translation unit containing D,
in either case prior to E[.](#dynamic-2.sentence-1)
[3](#dynamic-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7326)
Dynamic initialization of non-block variables V and W with static storage duration are ordered as follows:
- [(3.1)](#dynamic-3.1)
If V and W have ordered initialization and
the definition of V is appearance-ordered before the definition of W, or
if V has partially-ordered initialization,W does not have unordered initialization, and
for every definition E of W there exists a definition D of V such that D is appearance-ordered before E, then
* [(3.1.1)](#dynamic-3.1.1)
if the program does not start a thread ([[intro.multithread]](intro.multithread "6.10.2Multi-threaded executions and data races"))
other than the main thread ([[basic.start.main]](#main "6.10.3.1main function"))
or V and W have ordered initialization and
they are defined in the same translation unit,
the initialization of V is sequenced before
the initialization of W;
* [(3.1.2)](#dynamic-3.1.2)
otherwise,
the initialization of V strongly happens before
the initialization of W[.](#dynamic-3.1.sentence-1)
- [(3.2)](#dynamic-3.2)
Otherwise, if the program starts a thread
other than the main thread
before either V or W is initialized,
it is unspecified in which threads
the initializations of V and W occur;
the initializations are unsequenced if they occur in the same thread[.](#dynamic-3.2.sentence-1)
- [(3.3)](#dynamic-3.3)
Otherwise, the initializations of V and W are indeterminately sequenced[.](#dynamic-3.3.sentence-1)
[*Note [2](#dynamic-note-2)*:
This definition permits initialization of a sequence of
ordered variables concurrently with another sequence[.](#dynamic-3.sentence-2)
— *end note*]
[4](#dynamic-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7371)
A [*non-initialization odr-use*](#def:odr-use,non-initialization "6.10.3.3Dynamic initialization of non-block variables[basic.start.dynamic]") is an odr-use ([[basic.def.odr]](basic.def.odr#term.odr.use "6.3One-definition rule")) not caused directly or indirectly by
the initialization of a non-block static or thread storage duration variable[.](#dynamic-4.sentence-1)
[5](#dynamic-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7377)
It is implementation-defined
whether the dynamic initialization of a
non-block non-inline variable with static storage duration
is sequenced before the first statement of main or is deferred[.](#dynamic-5.sentence-1)
If it is deferred, it strongly happens before
any non-initialization odr-use
of any non-inline function or non-inline variable
defined in the same translation unit as the variable to be initialized[.](#dynamic-5.sentence-2)[38](#footnote-38 "A non-block variable with static storage duration having initialization with side effects is initialized in this case, even if it is not itself odr-used ([term.odr.use], [basic.stc.static]).")
It is implementation-defined
in which threads and at which points in the program such deferred dynamic initialization occurs[.](#dynamic-5.sentence-3)
*Recommended practice*: An implementation should choose such points in a way
that allows the programmer to avoid deadlocks[.](#dynamic-5.sentence-4)
[*Example [1](#dynamic-example-1)*: // - 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 the
initializations are delayed until a is first odr-used inmain[.](#dynamic-5.sentence-5)
In particular, if a is initialized beforemain is entered, 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[.](#dynamic-5.sentence-6)
If, however, a is initialized
at some point after the first statement of main, b will
be initialized prior to its use in A::A[.](#dynamic-5.sentence-7)
— *end example*]
[6](#dynamic-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7437)
It is implementation-defined
whether the dynamic initialization of a
non-block inline variable with static storage duration
is sequenced before the first statement of main or is deferred[.](#dynamic-6.sentence-1)
If it is deferred, it strongly happens before
any non-initialization odr-use
of that variable[.](#dynamic-6.sentence-2)
It is implementation-defined
in which threads and at which points in the program such deferred dynamic initialization occurs[.](#dynamic-6.sentence-3)
[7](#dynamic-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7448)
It is implementation-defined
whether the dynamic initialization of a
non-block non-inline variable with thread storage duration
is sequenced before the first statement of the initial function of a thread or is deferred[.](#dynamic-7.sentence-1)
If it is deferred,
the initialization associated with the entity for thread *t* is sequenced before the first non-initialization odr-use by *t* of any non-inline variable with thread storage duration
defined in the same translation unit as the variable to be initialized[.](#dynamic-7.sentence-2)
It is implementation-defined
in which threads and at which points in the program such deferred dynamic initialization occurs[.](#dynamic-7.sentence-3)
[8](#dynamic-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7461)
If the initialization of
a non-block variable with static or thread storage duration
exits via an exception,
the function std::terminate is called ([[except.terminate]](except.terminate "14.6.2The std::terminate function"))[.](#dynamic-8.sentence-1)
[38)](#footnote-38)[38)](#footnoteref-38)
A non-block variable with static storage duration
having initialization
with side effects is initialized in this case,
even if it is not itself odr-used ([[basic.def.odr]](basic.def.odr#term.odr.use "6.3One-definition rule"), [[basic.stc.static]](basic.stc.static "6.8.6.2Static storage duration"))[.](#footnote-38.sentence-1)
#### [6.10.3.4](#term) Termination [[basic.start.term]](basic.start.term)
[1](#term-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7470)
Constructed objects ([[dcl.init]](dcl.init "9.5Initializers"))
with static storage duration are destroyed
and functions registered with std::atexit are called as part of a call tostd::exit ([[support.start.term]](support.start.term "17.5Startup and termination"))[.](#term-1.sentence-1)
The call to std::exit is sequenced before
the destructions and the registered functions[.](#term-1.sentence-2)
[*Note [1](#term-note-1)*:
Returning from main invokes std::exit ([[basic.start.main]](#main "6.10.3.1main function"))[.](#term-1.sentence-3)
— *end note*]
[2](#term-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7487)
Constructed objects with thread storage duration within a given thread
are destroyed as a result of returning from the initial function of that thread and as a
result of that thread calling std::exit[.](#term-2.sentence-1)
The destruction of all constructed objects with thread storage
duration within that thread strongly happens before destroying
any object with static storage duration[.](#term-2.sentence-2)
[3](#term-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7495)
If the completion of the constructor or dynamic initialization of an object with static
storage duration strongly happens before that of another, the completion of the destructor
of the second is sequenced before the initiation of the destructor of the first[.](#term-3.sentence-1)
If the completion of the constructor or dynamic initialization of an object with thread
storage duration is sequenced before that of another, the completion of the destructor
of the second is sequenced before the initiation of the destructor of the first[.](#term-3.sentence-2)
If an object is
initialized statically, the object is destroyed in the same order as if
the object was dynamically initialized[.](#term-3.sentence-3)
For an object of array or class
type, all subobjects of that object are destroyed before any block
variable with static storage duration initialized during the construction
of the subobjects is destroyed[.](#term-3.sentence-4)
If the destruction of an object with static or thread storage duration
exits via an exception,
the function std::terminate is called ([[except.terminate]](except.terminate "14.6.2The std::terminate function"))[.](#term-3.sentence-5)
[4](#term-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7512)
If a function contains a block variable of static or thread storage duration that has been
destroyed and the function is called during the destruction of an object with static or
thread storage duration, the program has undefined behavior if the flow of control
passes through the definition of the previously destroyed block variable[.](#term-4.sentence-1)
[*Note [2](#term-note-2)*:
Likewise, the behavior is undefined
if the block variable is used indirectly (e.g., through a pointer)
after its destruction[.](#term-4.sentence-2)
— *end note*]
[5](#term-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7523)
If the completion of the initialization of an object with static storage
duration strongly happens before a call to std::atexit (see[<cstdlib>](cstdlib.syn#header:%3ccstdlib%3e "17.2.2Header <cstdlib> synopsis[cstdlib.syn]"), [[support.start.term]](support.start.term "17.5Startup and termination")), the call to the function passed tostd::atexit is sequenced before the call to the destructor for the object[.](#term-5.sentence-1)
If a
call to std::atexit strongly happens before the completion of the initialization of
an object with static storage duration, the call to the destructor for the
object is sequenced before the call to the function passed to std::atexit[.](#term-5.sentence-2)
If a
call to std::atexit strongly happens before another call to std::atexit, the
call to the function passed to the second std::atexit call is sequenced before
the call to the function passed to the first std::atexit call[.](#term-5.sentence-3)
[6](#term-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7537)
If there is a use of a standard library object or function not permitted within signal
handlers ([[support.runtime]](support.runtime "17.14Other runtime support")) that does not happen before ([[intro.multithread]](intro.multithread "6.10.2Multi-threaded executions and data races"))
completion of destruction of objects with static storage duration and execution ofstd::atexit registered functions ([[support.start.term]](support.start.term "17.5Startup and termination")), the program has
undefined behavior[.](#term-6.sentence-1)
[*Note [3](#term-note-3)*:
If there is a use of an object with static storage
duration that does not happen before the object's destruction, the program has undefined
behavior[.](#term-6.sentence-2)
Terminating every thread before a call to std::exit or the exit frommain is sufficient, but not necessary, to satisfy these requirements[.](#term-6.sentence-3)
These
requirements permit thread managers as static-storage-duration objects[.](#term-6.sentence-4)
— *end note*]
[7](#term-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7551)
Calling the function std::abort() declared in[<cstdlib>](cstdlib.syn#header:%3ccstdlib%3e "17.2.2Header <cstdlib> synopsis[cstdlib.syn]") terminates the program without executing any destructors
and without calling
the functions passed to std::atexit() or std::at_quick_exit()[.](#term-7.sentence-1)

View File

@@ -0,0 +1,187 @@
[basic.start.dynamic]
# 6 Basics [[basic]](./#basic)
## 6.10 Program execution [[basic.exec]](basic.exec#basic.start.dynamic)
### 6.10.3 Start and termination [[basic.start]](basic.start#dynamic)
#### 6.10.3.3 Dynamic initialization of non-block variables [basic.start.dynamic]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7302)
Dynamic initialization of a non-block variable with static storage duration is
unordered if the variable is an implicitly or explicitly instantiated
specialization, is partially-ordered if the variable
is an inline variable that is not an implicitly or explicitly instantiated
specialization, and otherwise is ordered[.](#1.sentence-1)
[*Note [1](#note-1)*:
A non-inline explicit specialization of a templated variable
has ordered initialization[.](#1.sentence-2)
— *end note*]
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7316)
A declaration D is[*appearance-ordered*](#def:appearance-ordered "6.10.3.3Dynamic initialization of non-block variables[basic.start.dynamic]") before a declaration E if
- [(2.1)](#2.1)
D appears in the same translation unit as E, or
- [(2.2)](#2.2)
the translation unit containing E has an interface dependency on the translation unit containing D,
in either case prior to E[.](#2.sentence-1)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7326)
Dynamic initialization of non-block variables V and W with static storage duration are ordered as follows:
- [(3.1)](#3.1)
If V and W have ordered initialization and
the definition of V is appearance-ordered before the definition of W, or
if V has partially-ordered initialization,W does not have unordered initialization, and
for every definition E of W there exists a definition D of V such that D is appearance-ordered before E, then
* [(3.1.1)](#3.1.1)
if the program does not start a thread ([[intro.multithread]](intro.multithread "6.10.2Multi-threaded executions and data races"))
other than the main thread ([[basic.start.main]](basic.start.main "6.10.3.1main function"))
or V and W have ordered initialization and
they are defined in the same translation unit,
the initialization of V is sequenced before
the initialization of W;
* [(3.1.2)](#3.1.2)
otherwise,
the initialization of V strongly happens before
the initialization of W[.](#3.1.sentence-1)
- [(3.2)](#3.2)
Otherwise, if the program starts a thread
other than the main thread
before either V or W is initialized,
it is unspecified in which threads
the initializations of V and W occur;
the initializations are unsequenced if they occur in the same thread[.](#3.2.sentence-1)
- [(3.3)](#3.3)
Otherwise, the initializations of V and W are indeterminately sequenced[.](#3.3.sentence-1)
[*Note [2](#note-2)*:
This definition permits initialization of a sequence of
ordered variables concurrently with another sequence[.](#3.sentence-2)
— *end note*]
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7371)
A [*non-initialization odr-use*](#def:odr-use,non-initialization "6.10.3.3Dynamic initialization of non-block variables[basic.start.dynamic]") is an odr-use ([[basic.def.odr]](basic.def.odr#term.odr.use "6.3One-definition rule")) not caused directly or indirectly by
the initialization of a non-block static or thread storage duration variable[.](#4.sentence-1)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7377)
It is implementation-defined
whether the dynamic initialization of a
non-block non-inline variable with static storage duration
is sequenced before the first statement of main or is deferred[.](#5.sentence-1)
If it is deferred, it strongly happens before
any non-initialization odr-use
of any non-inline function or non-inline variable
defined in the same translation unit as the variable to be initialized[.](#5.sentence-2)[38](#footnote-38 "A non-block variable with static storage duration having initialization with side effects is initialized in this case, even if it is not itself odr-used ([term.odr.use], [basic.stc.static]).")
It is implementation-defined
in which threads and at which points in the program such deferred dynamic initialization occurs[.](#5.sentence-3)
*Recommended practice*: An implementation should choose such points in a way
that allows the programmer to avoid deadlocks[.](#5.sentence-4)
[*Example [1](#example-1)*: // - 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 the
initializations are delayed until a is first odr-used inmain[.](#5.sentence-5)
In particular, if a is initialized beforemain is entered, 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[.](#5.sentence-6)
If, however, a is initialized
at some point after the first statement of main, b will
be initialized prior to its use in A::A[.](#5.sentence-7)
— *end example*]
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7437)
It is implementation-defined
whether the dynamic initialization of a
non-block inline variable with static storage duration
is sequenced before the first statement of main or is deferred[.](#6.sentence-1)
If it is deferred, it strongly happens before
any non-initialization odr-use
of that variable[.](#6.sentence-2)
It is implementation-defined
in which threads and at which points in the program such deferred dynamic initialization occurs[.](#6.sentence-3)
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7448)
It is implementation-defined
whether the dynamic initialization of a
non-block non-inline variable with thread storage duration
is sequenced before the first statement of the initial function of a thread or is deferred[.](#7.sentence-1)
If it is deferred,
the initialization associated with the entity for thread *t* is sequenced before the first non-initialization odr-use by *t* of any non-inline variable with thread storage duration
defined in the same translation unit as the variable to be initialized[.](#7.sentence-2)
It is implementation-defined
in which threads and at which points in the program such deferred dynamic initialization occurs[.](#7.sentence-3)
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7461)
If the initialization of
a non-block variable with static or thread storage duration
exits via an exception,
the function std::terminate is called ([[except.terminate]](except.terminate "14.6.2The std::terminate function"))[.](#8.sentence-1)
[38)](#footnote-38)[38)](#footnoteref-38)
A non-block variable with static storage duration
having initialization
with side effects is initialized in this case,
even if it is not itself odr-used ([[basic.def.odr]](basic.def.odr#term.odr.use "6.3One-definition rule"), [[basic.stc.static]](basic.stc.static "6.8.6.2Static storage duration"))[.](#footnote-38.sentence-1)

View File

@@ -0,0 +1,141 @@
[basic.start.main]
# 6 Basics [[basic]](./#basic)
## 6.10 Program execution [[basic.exec]](basic.exec#basic.start.main)
### 6.10.3 Start and termination [[basic.start]](basic.start#main)
#### 6.10.3.1 main function [basic.start.main]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7129)
A program shall contain exactly one function called main that belongs to the global scope[.](#1.sentence-1)
Executing a program starts a main thread of execution ([[intro.multithread]](intro.multithread "6.10.2Multi-threaded executions and data races"), [[thread.threads]](thread.threads "32.4Threads"))
in which the main function is invoked[.](#1.sentence-2)
It is implementation-defined
whether a program in a freestanding environment is required to define a main function[.](#1.sentence-3)
[*Note [1](#note-1)*:
In a freestanding environment, startup and termination isimplementation-defined; startup contains the
execution of constructors for non-local objects with static storage duration;
termination contains the execution of destructors for objects with static storage
duration[.](#1.sentence-4)
— *end note*]
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7147)
An implementation shall not predefine the main function[.](#2.sentence-1)
Its type shall have C++ language linkage
and it shall have a declared return type of typeint, but otherwise its type is implementation-defined[.](#2.sentence-2)
An implementation shall allow both
- [(2.1)](#2.1)
a function of () returning int and
- [(2.2)](#2.2)
a function of (int, pointer to pointer to char) returning int
as the type of main ([[dcl.fct]](dcl.fct "9.3.4.6Functions"))[.](#2.sentence-3)
In the latter form, for purposes of exposition, the first function
parameter is called argc and the second function parameter is
called argv, where argc shall be the number of
arguments passed to the program from the environment in which the
program is run[.](#2.sentence-4)
Ifargc is nonzero these arguments shall be supplied inargv[0] through argv[argc - 1] as pointers to the initial
characters of null-terminated multibyte strings (ntmbss) ([[multibyte.strings]](multibyte.strings "16.3.3.3.4.3Multibyte strings"))
and argv[0] shall be the pointer to
the initial character of an ntmbs that represents the name used to
invoke the program or ""[.](#2.sentence-5)
The value of argc shall be
non-negative[.](#2.sentence-6)
The value of argv[argc] shall be 0[.](#2.sentence-7)
*Recommended practice*: Any further (optional) parameters should be added after argv[.](#2.sentence-8)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7179)
The function main shall not be named by an expression[.](#3.sentence-1)
The linkage ([[basic.link]](basic.link "6.7Program and linkage")) of main isimplementation-defined[.](#3.sentence-2)
A program that defines main as
deleted or that declares main to beinline, static, constexpr, or consteval is ill-formed[.](#3.sentence-3)
The function main shall not be a coroutine ([[dcl.fct.def.coroutine]](dcl.fct.def.coroutine "9.6.4Coroutine definitions"))[.](#3.sentence-4)
The main function shall not be declared with a[*linkage-specification*](dcl.link#nt:linkage-specification "9.12Linkage specifications[dcl.link]") ([[dcl.link]](dcl.link "9.12Linkage specifications")) other than "C++"[.](#3.sentence-5)
A program that declares
- [(3.1)](#3.1)
a variable main that belongs to the global scope, or
- [(3.2)](#3.2)
a function main that belongs to the global scope and
is attached to a named module, or
- [(3.3)](#3.3)
a function template main that belongs to the global scope, or
- [(3.4)](#3.4)
an entity named main with C language linkage (in any namespace)
is ill-formed[.](#3.sentence-6)
The name main is
not otherwise reserved[.](#3.sentence-7)
[*Example [1](#example-1)*:
Member functions, classes, and
enumerations can be called main, as can entities in other
namespaces[.](#3.sentence-8)
— *end example*]
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7211)
Terminating the program
without leaving the current block (e.g., by calling the functionstd::exit(int) ([[support.start.term]](support.start.term "17.5Startup and termination"))) does not destroy any
objects with automatic storage duration ([[class.dtor]](class.dtor "11.4.7Destructors"))[.](#4.sentence-1)
Ifstd::exit is invoked during the destruction of
an object with static or thread storage duration, the program has undefined
behavior[.](#4.sentence-2)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7223)
A return statement ([[stmt.return]](stmt.return "8.8.4The return statement")) in main has the effect of leaving the main function (destroying any objects with automatic storage duration
and evaluating any postcondition assertions of main)
and calling std::exit with the return value as the argument[.](#5.sentence-1)
If control flows off the end of
the [*compound-statement*](stmt.block#nt:compound-statement "8.4Compound statement or block[stmt.block]") of main,
the effect is equivalent to a return with operand 0 (see also [[except.handle]](except.handle "14.4Handling an exception"))[.](#5.sentence-2)

View File

@@ -0,0 +1,81 @@
[basic.start.static]
# 6 Basics [[basic]](./#basic)
## 6.10 Program execution [[basic.exec]](basic.exec#basic.start.static)
### 6.10.3 Start and termination [[basic.start]](basic.start#static)
#### 6.10.3.2 Static initialization [basic.start.static]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7238)
Variables with static storage duration
are initialized as a consequence of program initiation[.](#1.sentence-1)
Variables with
thread storage duration are initialized as a consequence of thread execution[.](#1.sentence-2)
Within each of these phases of initiation, initialization occurs as follows[.](#1.sentence-3)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7246)
[*Constant initialization*](#def:constant_initialization "6.10.3.2Static initialization[basic.start.static]") is performed
if a variable with static or thread storage duration
is constant-initialized ([[expr.const]](expr.const "7.7Constant expressions"))[.](#2.sentence-1)
If constant initialization is not performed, a variable with static
storage duration ([[basic.stc.static]](basic.stc.static "6.8.6.2Static storage duration")) or thread storage
duration ([[basic.stc.thread]](basic.stc.thread "6.8.6.3Thread storage duration")) is zero-initialized ([[dcl.init]](dcl.init "9.5Initializers"))[.](#2.sentence-2)
Together, zero-initialization and constant initialization are called[*static initialization*](#def:initialization,static "6.10.3.2Static initialization[basic.start.static]");
all other initialization is [*dynamic initialization*](#def:initialization,dynamic "6.10.3.2Static initialization[basic.start.static]")[.](#2.sentence-3)
All static initialization strongly happens before ([[intro.races]](intro.races "6.10.2.2Data races"))
any dynamic initialization[.](#2.sentence-4)
[*Note [1](#note-1)*:
The dynamic initialization of non-block variables is described
in [[basic.start.dynamic]](basic.start.dynamic "6.10.3.3Dynamic initialization of non-block variables"); that of static block variables is described
in [[stmt.dcl]](stmt.dcl "8.10Declaration statement")[.](#2.sentence-5)
— *end note*]
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7266)
An implementation is permitted to perform the initialization of a
variable with static or thread storage duration as a static
initialization even if such initialization is not required to be done
statically, provided that
- [(3.1)](#3.1)
the dynamic version of the initialization does not change the
value of any other object of static or thread storage duration
prior to its initialization, and
- [(3.2)](#3.2)
the static version of the initialization produces the same value
in the initialized variable as would be produced by the dynamic
initialization if all variables not required to be initialized statically
were initialized dynamically[.](#3.sentence-1)
[*Note [2](#note-2)*:
As a consequence, if the initialization of an object obj1 refers to an
object obj2 potentially requiring dynamic initialization and defined
later in the same translation unit, it is unspecified whether the value of obj2 used
will be the value of the fully initialized obj2 (because obj2 was statically
initialized) or will be the value of obj2 merely zero-initialized[.](#3.sentence-2)
For example,inline double fd() { return 1.0; }extern double d1;double d2 = d1; // unspecified:// either statically initialized to 0.0 or// dynamically initialized to 0.0 if d1 is// dynamically initialized, or 1.0 otherwisedouble d1 = fd(); // either initialized statically or dynamically to 1.0
— *end note*]

View File

@@ -0,0 +1,127 @@
[basic.start.term]
# 6 Basics [[basic]](./#basic)
## 6.10 Program execution [[basic.exec]](basic.exec#basic.start.term)
### 6.10.3 Start and termination [[basic.start]](basic.start#term)
#### 6.10.3.4 Termination [basic.start.term]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7470)
Constructed objects ([[dcl.init]](dcl.init "9.5Initializers"))
with static storage duration are destroyed
and functions registered with std::atexit are called as part of a call tostd::exit ([[support.start.term]](support.start.term "17.5Startup and termination"))[.](#1.sentence-1)
The call to std::exit is sequenced before
the destructions and the registered functions[.](#1.sentence-2)
[*Note [1](#note-1)*:
Returning from main invokes std::exit ([[basic.start.main]](basic.start.main "6.10.3.1main function"))[.](#1.sentence-3)
— *end note*]
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7487)
Constructed objects with thread storage duration within a given thread
are destroyed as a result of returning from the initial function of that thread and as a
result of that thread calling std::exit[.](#2.sentence-1)
The destruction of all constructed objects with thread storage
duration within that thread strongly happens before destroying
any object with static storage duration[.](#2.sentence-2)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7495)
If the completion of the constructor or dynamic initialization of an object with static
storage duration strongly happens before that of another, the completion of the destructor
of the second is sequenced before the initiation of the destructor of the first[.](#3.sentence-1)
If the completion of the constructor or dynamic initialization of an object with thread
storage duration is sequenced before that of another, the completion of the destructor
of the second is sequenced before the initiation of the destructor of the first[.](#3.sentence-2)
If an object is
initialized statically, the object is destroyed in the same order as if
the object was dynamically initialized[.](#3.sentence-3)
For an object of array or class
type, all subobjects of that object are destroyed before any block
variable with static storage duration initialized during the construction
of the subobjects is destroyed[.](#3.sentence-4)
If the destruction of an object with static or thread storage duration
exits via an exception,
the function std::terminate is called ([[except.terminate]](except.terminate "14.6.2The std::terminate function"))[.](#3.sentence-5)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7512)
If a function contains a block variable of static or thread storage duration that has been
destroyed and the function is called during the destruction of an object with static or
thread storage duration, the program has undefined behavior if the flow of control
passes through the definition of the previously destroyed block variable[.](#4.sentence-1)
[*Note [2](#note-2)*:
Likewise, the behavior is undefined
if the block variable is used indirectly (e.g., through a pointer)
after its destruction[.](#4.sentence-2)
— *end note*]
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7523)
If the completion of the initialization of an object with static storage
duration strongly happens before a call to std::atexit (see[<cstdlib>](cstdlib.syn#header:%3ccstdlib%3e "17.2.2Header <cstdlib> synopsis[cstdlib.syn]"), [[support.start.term]](support.start.term "17.5Startup and termination")), the call to the function passed tostd::atexit is sequenced before the call to the destructor for the object[.](#5.sentence-1)
If a
call to std::atexit strongly happens before the completion of the initialization of
an object with static storage duration, the call to the destructor for the
object is sequenced before the call to the function passed to std::atexit[.](#5.sentence-2)
If a
call to std::atexit strongly happens before another call to std::atexit, the
call to the function passed to the second std::atexit call is sequenced before
the call to the function passed to the first std::atexit call[.](#5.sentence-3)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7537)
If there is a use of a standard library object or function not permitted within signal
handlers ([[support.runtime]](support.runtime "17.14Other runtime support")) that does not happen before ([[intro.multithread]](intro.multithread "6.10.2Multi-threaded executions and data races"))
completion of destruction of objects with static storage duration and execution ofstd::atexit registered functions ([[support.start.term]](support.start.term "17.5Startup and termination")), the program has
undefined behavior[.](#6.sentence-1)
[*Note [3](#note-3)*:
If there is a use of an object with static storage
duration that does not happen before the object's destruction, the program has undefined
behavior[.](#6.sentence-2)
Terminating every thread before a call to std::exit or the exit frommain is sufficient, but not necessary, to satisfy these requirements[.](#6.sentence-3)
These
requirements permit thread managers as static-storage-duration objects[.](#6.sentence-4)
— *end note*]
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L7551)
Calling the function std::abort() declared in[<cstdlib>](cstdlib.syn#header:%3ccstdlib%3e "17.2.2Header <cstdlib> synopsis[cstdlib.syn]") terminates the program without executing any destructors
and without calling
the functions passed to std::atexit() or std::at_quick_exit()[.](#7.sentence-1)

494
cppdraft/basic/stc.md Normal file
View File

@@ -0,0 +1,494 @@
[basic.stc]
# 6 Basics [[basic]](./#basic)
## 6.8 Memory and objects [[basic.memobj]](basic.memobj#basic.stc)
### 6.8.6 Storage duration [basic.stc]
#### [6.8.6.1](#general) General [[basic.stc.general]](basic.stc.general)
[1](#general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4244)
The [*storage duration*](#def:storage_duration "6.8.6.1General[basic.stc.general]") is the property of an object that defines the minimum
potential lifetime of the storage containing the object[.](#general-1.sentence-1)
The storage
duration is determined by the construct used to create the object and is
one of the following:
- [(1.1)](#general-1.1)
static storage duration
- [(1.2)](#general-1.2)
thread storage duration
- [(1.3)](#general-1.3)
automatic storage duration
- [(1.4)](#general-1.4)
dynamic storage duration
[*Note [1](#general-note-1)*:
After the duration of a region of storage has ended,
the use of pointers to that region of storage is limited ([[basic.compound]](basic.compound "6.9.4Compound types"))[.](#general-1.sentence-2)
— *end note*]
[2](#general-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4261)
Static, thread, and automatic storage durations are associated with objects
introduced by declarations ([[basic.def]](basic.def "6.2Declarations and definitions")) and
with temporary objects ([[class.temporary]](class.temporary "6.8.7Temporary objects"))[.](#general-2.sentence-1)
The dynamic storage duration
is associated with objects created by a[*new-expression*](expr.new#nt:new-expression "7.6.2.8New[expr.new]") ([[expr.new]](expr.new "7.6.2.8New")) or
with implicitly created objects ([[intro.object]](intro.object "6.8.2Object model"))[.](#general-2.sentence-2)
[3](#general-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4274)
The storage duration categories apply to references as well[.](#general-3.sentence-1)
[4](#general-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4277)
The storage duration of subobjects and reference members
is that of their complete object ([[intro.object]](intro.object "6.8.2Object model"))[.](#general-4.sentence-1)
#### [6.8.6.2](#static) Static storage duration [[basic.stc.static]](basic.stc.static)
[1](#static-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4285)
All variables which
- [(1.1)](#static-1.1)
do not have thread storage duration and
- [(1.2)](#static-1.2)
belong to a namespace scope ([[basic.scope.namespace]](basic.scope.namespace "6.4.6Namespace scope")) or
are first declared with
the static or extern keywords ([[dcl.stc]](dcl.stc "9.2.2Storage class specifiers"))
have [*static storage duration*](#def:storage_duration,static "6.8.6.2Static storage duration[basic.stc.static]")[.](#static-1.sentence-1)
The storage for these entities lasts for the duration of the
program ([[basic.start.static]](basic.start.static "6.10.3.2Static initialization"), [[basic.start.term]](basic.start.term "6.10.3.4Termination"))[.](#static-1.sentence-2)
[2](#static-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4299)
If a 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/move may be
eliminated as specified in [[class.copy.elision]](class.copy.elision "11.9.6Copy/move elision")[.](#static-2.sentence-1)
[3](#static-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4305)
[*Note [1](#static-note-1)*:
The keyword static can be used to declare
a block variable ([[basic.scope.block]](basic.scope.block "6.4.3Block scope")) with static storage duration;[[stmt.dcl]](stmt.dcl "8.10Declaration statement") and [[basic.start.term]](basic.start.term "6.10.3.4Termination") describe the
initialization and destruction of such variables[.](#static-3.sentence-1)
The keyword static applied to
a class data member in a class definition
gives the data member static storage duration ([[class.static.data]](class.static.data "11.4.9.3Static data members"))[.](#static-3.sentence-2)
— *end note*]
#### [6.8.6.3](#thread) Thread storage duration [[basic.stc.thread]](basic.stc.thread)
[1](#thread-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4320)
All variables declared with the thread_local keyword have[*thread storage duration*](#def:storage_duration,thread "6.8.6.3Thread storage duration[basic.stc.thread]")[.](#thread-1.sentence-1)
The storage for these entities lasts for the duration of
the thread in which they are created[.](#thread-1.sentence-2)
There is a distinct object or reference
per thread, and use of the declared name refers to the entity associated with
the current thread[.](#thread-1.sentence-3)
[2](#thread-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4328)
[*Note [1](#thread-note-1)*:
A variable with thread storage duration is initialized as specified
in [[basic.start.static]](basic.start.static "6.10.3.2Static initialization"), [[basic.start.dynamic]](basic.start.dynamic "6.10.3.3Dynamic initialization of non-block variables"), and [[stmt.dcl]](stmt.dcl "8.10Declaration statement") and, if constructed, is destroyed on thread exit ([[basic.start.term]](basic.start.term "6.10.3.4Termination"))[.](#thread-2.sentence-1)
— *end note*]
#### [6.8.6.4](#auto) Automatic storage duration [[basic.stc.auto]](basic.stc.auto)
[1](#auto-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4337)
Variables that belong to a block scope and are
not explicitly declared static, thread_local, or extern have[*automatic storage duration*](#def:storage_duration,automatic "6.8.6.4Automatic storage duration[basic.stc.auto]")[.](#auto-1.sentence-1)
The storage
for such variables lasts until the block in which they are created exits[.](#auto-1.sentence-2)
[*Note [1](#auto-note-1)*:
These variables are initialized and destroyed as described in [[stmt.dcl]](stmt.dcl "8.10Declaration statement")[.](#auto-1.sentence-3)
— *end note*]
Variables that belong to a parameter scope also have automatic storage duration[.](#auto-1.sentence-4)
The storage for a function parameter lasts until
immediately after its destruction ([[expr.call]](expr.call "7.6.1.3Function call"))[.](#auto-1.sentence-5)
[2](#auto-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4350)
If a variable with automatic storage duration has initialization or a destructor with side
effects, an implementation shall not destroy it before the end of its block
nor eliminate it as an optimization, even if it appears to be
unused, except that a class object or its copy/move may be eliminated as
specified in [[class.copy.elision]](class.copy.elision "11.9.6Copy/move elision")[.](#auto-2.sentence-1)
#### [6.8.6.5](#dynamic) Dynamic storage duration [[basic.stc.dynamic]](basic.stc.dynamic)
#### [6.8.6.5.1](#dynamic.general) General [[basic.stc.dynamic.general]](basic.stc.dynamic.general)
[1](#dynamic.general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4362)
Objects can be created dynamically during [program
execution](intro.execution "6.10.1Sequential execution[intro.execution]"), using[*new-expression*](expr.new#nt:new-expression "7.6.2.8New[expr.new]")*s* ([[expr.new]](expr.new "7.6.2.8New")), and destroyed using[*delete-expression*](expr.delete#nt:delete-expression "7.6.2.9Delete[expr.delete]")*s* ([[expr.delete]](expr.delete "7.6.2.9Delete"))[.](#dynamic.general-1.sentence-1)
A C++ implementation
provides access to, and management of, dynamic storage via
the global [*allocation functions*](#def:allocation_function "6.8.6.5.1General[basic.stc.dynamic.general]")operator new andoperator new[] and
the global [*deallocation functions*](#def:deallocation_function "6.8.6.5.1General[basic.stc.dynamic.general]")operator delete andoperator delete[][.](#dynamic.general-1.sentence-2)
[*Note [1](#dynamic.general-note-1)*:
The non-allocating forms described in [[new.delete.placement]](new.delete.placement "17.6.3.4Non-allocating forms") do not perform allocation or deallocation[.](#dynamic.general-1.sentence-3)
— *end note*]
[2](#dynamic.general-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4381)
The library provides default definitions for the global allocation and
deallocation functions[.](#dynamic.general-2.sentence-1)
Some global allocation and deallocation
functions are replaceable ([[dcl.fct.def.replace]](dcl.fct.def.replace#term.replaceable.function "9.6.5Replaceable function definitions"))[.](#dynamic.general-2.sentence-2)
The following allocation and deallocation functions ([[support.dynamic]](support.dynamic "17.6Dynamic memory management"))
are implicitly declared in global scope in each translation unit of a
program[.](#dynamic.general-2.sentence-3)
void* operator new(std::size_t);void* operator new(std::size_t, std::align_val_t);
void operator delete(void*) noexcept;void operator delete(void*, std::size_t) noexcept;void operator delete(void*, std::align_val_t) noexcept;void operator delete(void*, std::size_t, std::align_val_t) noexcept;
void* operator new[](std::size_t);void* operator new[](std::size_t, std::align_val_t);
void operator delete[](void*) noexcept;void operator delete[](void*, std::size_t) noexcept;void operator delete[](void*, std::align_val_t) noexcept;void operator delete[](void*, std::size_t, std::align_val_t) noexcept;
These implicit declarations introduce only the function namesoperator new,operator new[],operator delete, andoperator delete[][.](#dynamic.general-2.sentence-4)
[*Note [2](#dynamic.general-note-2)*:
The implicit declarations do not introduce
the names std,std::size_t,std::align_val_t,
or any other names that the library uses to
declare these names[.](#dynamic.general-2.sentence-5)
Thus, a [*new-expression*](expr.new#nt:new-expression "7.6.2.8New[expr.new]"),[*delete-expression*](expr.delete#nt:delete-expression "7.6.2.9Delete[expr.delete]"), or function call that refers to one of
these functions without importing or including the header [<new>](support.dynamic.general#header:%3cnew%3e "17.6.1General[support.dynamic.general]") or importing a C++ library module ([[std.modules]](std.modules "16.4.2.4Modules"))
is well-formed[.](#dynamic.general-2.sentence-6)
However, referring to std or std::size_t or std::align_val_t is ill-formed unless
a standard library declaration ([[cstddef.syn]](cstddef.syn "17.2.1Header <cstddef> synopsis"), [[new.syn]](new.syn "17.6.2Header <new> synopsis"), [[std.modules]](std.modules "16.4.2.4Modules"))
of that name precedes ([[basic.lookup.general]](basic.lookup.general "6.5.1General")) the use of that name[.](#dynamic.general-2.sentence-7)
— *end note*]
Allocation and/or
deallocation functions may also be declared and defined for any
class ([[class.free]](class.free "11.4.11Allocation and deallocation functions"))[.](#dynamic.general-2.sentence-8)
[3](#dynamic.general-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4433)
If the behavior of an allocation or deallocation function
does not satisfy the semantic constraints
specified in [[basic.stc.dynamic.allocation]](#dynamic.allocation "6.8.6.5.2Allocation functions") and [[basic.stc.dynamic.deallocation]](#dynamic.deallocation "6.8.6.5.3Deallocation functions"),
the behavior is undefined[.](#dynamic.general-3.sentence-1)
#### [6.8.6.5.2](#dynamic.allocation) Allocation functions [[basic.stc.dynamic.allocation]](basic.stc.dynamic.allocation)
[1](#dynamic.allocation-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4444)
An allocation function that is not a class member function
shall belong to the global scope and not have a name with internal linkage[.](#dynamic.allocation-1.sentence-1)
The return type shall be void*[.](#dynamic.allocation-1.sentence-2)
The first
parameter shall have type std::size_t ([[support.types]](support.types "17.2Common definitions"))[.](#dynamic.allocation-1.sentence-3)
The
first parameter shall not have an associated default
argument ([[dcl.fct.default]](dcl.fct.default "9.3.4.7Default arguments"))[.](#dynamic.allocation-1.sentence-4)
The value of the first parameter
is interpreted as the requested size of the allocation[.](#dynamic.allocation-1.sentence-5)
An allocation
function can be a function template[.](#dynamic.allocation-1.sentence-6)
Such a template shall declare its
return type and first parameter as specified above (that is, template
parameter types shall not be used in the return type and first parameter
type)[.](#dynamic.allocation-1.sentence-7)
Allocation function templates shall have two or more parameters[.](#dynamic.allocation-1.sentence-8)
[2](#dynamic.allocation-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4458)
An allocation function attempts to allocate the requested amount of
storage[.](#dynamic.allocation-2.sentence-1)
If it is successful, it returns the address of the start
of a block of storage whose length in bytes is at least as large
as the requested size[.](#dynamic.allocation-2.sentence-2)
The order,
contiguity, and initial value of storage allocated by successive calls
to an allocation function are unspecified[.](#dynamic.allocation-2.sentence-3)
Even if the size of the space
requested is zero, the request can fail[.](#dynamic.allocation-2.sentence-4)
If the request succeeds, the
value returned by a replaceable allocation function
is a non-null pointer value ([[basic.compound]](basic.compound "6.9.4Compound types"))p0 different from any previously returned value p1,
unless that value p1 was subsequently passed to a
replaceable deallocation function[.](#dynamic.allocation-2.sentence-5)
Furthermore, for the library allocation functions
in [[new.delete.single]](new.delete.single "17.6.3.2Single-object forms") and [[new.delete.array]](new.delete.array "17.6.3.3Array forms"),p0 represents the address of a block of storage disjoint from the storage
for any other object accessible to the caller[.](#dynamic.allocation-2.sentence-6)
The effect of indirecting through a pointer
returned from a request for zero size is undefined[.](#dynamic.allocation-2.sentence-7)[23](#footnote-23 "The intent is to have operator new() implementable by calling std::malloc() or std::calloc(), so the rules are substantially the same. C++ differs from C in requiring a zero request to return a non-null pointer.")
[3](#dynamic.allocation-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4487)
For an allocation function other than
a reserved placement allocation function ([[new.delete.placement]](new.delete.placement "17.6.3.4Non-allocating forms")),
the pointer returned on a successful call
shall represent the address of storage that is aligned as follows:
- [(3.1)](#dynamic.allocation-3.1)
If the allocation function takes an argument
of type std::align_val_t,
the storage will have the alignment specified
by the value of this argument[.](#dynamic.allocation-3.1.sentence-1)
- [(3.2)](#dynamic.allocation-3.2)
Otherwise, if the allocation function is named operator new[],
the storage is aligned for any object that
does not have new-extended alignment ([[basic.align]](basic.align "6.8.3Alignment")) and
is no larger than the requested size[.](#dynamic.allocation-3.2.sentence-1)
- [(3.3)](#dynamic.allocation-3.3)
Otherwise, the storage is aligned for any object that
does not have new-extended alignment and is of the requested size[.](#dynamic.allocation-3.3.sentence-1)
[4](#dynamic.allocation-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4508)
An allocation function that fails to allocate storage can invoke the
currently installed new-handler function ([[new.handler]](new.handler "17.6.4.3Type new_­handler")), if any[.](#dynamic.allocation-4.sentence-1)
[*Note [1](#dynamic.allocation-note-1)*:
A program-supplied allocation function can obtain the
currently installed new_handler using thestd::get_new_handler function ([[get.new.handler]](get.new.handler "17.6.4.5get_­new_­handler"))[.](#dynamic.allocation-4.sentence-2)
— *end note*]
An allocation function that has a non-throwing
exception specification ([[except.spec]](except.spec "14.5Exception specifications"))
indicates failure by returning
a null pointer value[.](#dynamic.allocation-4.sentence-3)
Any other allocation function
never returns a null pointer value and
indicates failure only by throwing an exception ([[except.throw]](except.throw "14.2Throwing an exception")) of a type
that would match a handler ([[except.handle]](except.handle "14.4Handling an exception")) of typestd::bad_alloc ([[bad.alloc]](bad.alloc "17.6.4.1Class bad_­alloc"))[.](#dynamic.allocation-4.sentence-4)
[5](#dynamic.allocation-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4527)
A global allocation function is only called as the result of a [new
expression](expr.new "7.6.2.8New[expr.new]"), or called directly using the [function call](expr.call "7.6.1.3Function call[expr.call]") syntax, or called indirectly to allocate storage for
a coroutine state ([[dcl.fct.def.coroutine]](dcl.fct.def.coroutine "9.6.4Coroutine definitions")),
or called indirectly through calls to the
functions in the C++ standard library[.](#dynamic.allocation-5.sentence-1)
[*Note [2](#dynamic.allocation-note-2)*:
In particular, a
global allocation function is not called to allocate storage
for objects with static storage duration ([[basic.stc.static]](#static "6.8.6.2Static storage duration")),
for objects or references with thread storage duration ([[basic.stc.thread]](#thread "6.8.6.3Thread storage duration")),
for objects of type std::type_info ([[expr.typeid]](expr.typeid "7.6.1.8Type identification")),
for an object of type std::contracts::contract_violation when a contract violation occurs ([[basic.contract.eval]](basic.contract.eval "6.11.2Evaluation")), or
for an exception object ([[except.throw]](except.throw "14.2Throwing an exception"))[.](#dynamic.allocation-5.sentence-2)
— *end note*]
[23)](#footnote-23)[23)](#footnoteref-23)
The intent is
to have operator new() implementable by
calling std::malloc() or std::calloc(), so the rules are
substantially the same[.](#footnote-23.sentence-1)
C++ differs from C in requiring a zero request
to return a non-null pointer[.](#footnote-23.sentence-2)
#### [6.8.6.5.3](#dynamic.deallocation) Deallocation functions [[basic.stc.dynamic.deallocation]](basic.stc.dynamic.deallocation)
[1](#dynamic.deallocation-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4547)
A deallocation function that is not a class member function
shall belong to the global scope and not have a name with internal linkage[.](#dynamic.deallocation-1.sentence-1)
[2](#dynamic.deallocation-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4552)
A deallocation function
is a [*destroying operator delete*](#def:operator_delete,destroying "6.8.6.5.3Deallocation functions[basic.stc.dynamic.deallocation]") if it has at least two parameters
and its second parameter
is of type std::destroying_delete_t[.](#dynamic.deallocation-2.sentence-1)
A destroying operator delete
shall be a class member function named operator delete[.](#dynamic.deallocation-2.sentence-2)
[*Note [1](#dynamic.deallocation-note-1)*:
Array deletion cannot use a destroying operator delete[.](#dynamic.deallocation-2.sentence-3)
— *end note*]
[3](#dynamic.deallocation-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4564)
Each deallocation function shall return void[.](#dynamic.deallocation-3.sentence-1)
If the function is a destroying operator delete
declared in class type C,
the type of its first parameter shall be C*;
otherwise, the type of its first
parameter shall be void*[.](#dynamic.deallocation-3.sentence-2)
A deallocation function may have more
than one parameter[.](#dynamic.deallocation-3.sentence-3)
A [*usual deallocation function*](#def:usual_deallocation_function "6.8.6.5.3Deallocation functions[basic.stc.dynamic.deallocation]") is a deallocation function
whose parameters after the first are
- [(3.1)](#dynamic.deallocation-3.1)
optionally, a parameter of type std::destroying_delete_t, then
- [(3.2)](#dynamic.deallocation-3.2)
optionally, a parameter of type std::size_t,[24](#footnote-24 "The global operator delete(void*, std::size_­t) precludes use of an allocation function void operator new(std::size_­t, std::size_­t) as a placement allocation function ([diff.cpp11.basic]).") then
- [(3.3)](#dynamic.deallocation-3.3)
optionally, a parameter of type std::align_val_t[.](#dynamic.deallocation-3.sentence-4)
A destroying operator delete shall be a usual deallocation function[.](#dynamic.deallocation-3.sentence-5)
A deallocation function may be an instance of a function
template[.](#dynamic.deallocation-3.sentence-6)
Neither the first parameter nor the return type shall depend
on a template parameter[.](#dynamic.deallocation-3.sentence-7)
A deallocation
function template shall have two or more function parameters[.](#dynamic.deallocation-3.sentence-8)
A template
instance is never a usual deallocation function, regardless of its
signature[.](#dynamic.deallocation-3.sentence-9)
[4](#dynamic.deallocation-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4600)
If a deallocation function terminates by throwing an exception, the behavior is undefined[.](#dynamic.deallocation-4.sentence-1)
The value of the first argument supplied to a deallocation function may
be a null pointer value; if so, and if the deallocation function is one
supplied in the standard library, the call has no effect[.](#dynamic.deallocation-4.sentence-2)
[5](#dynamic.deallocation-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4606)
If the argument given to a deallocation function in the standard library
is a pointer that is not the null pointer value ([[basic.compound]](basic.compound "6.9.4Compound types")), the
deallocation function shall deallocate the storage referenced by the
pointer, ending the duration of the region of storage[.](#dynamic.deallocation-5.sentence-1)
[24)](#footnote-24)[24)](#footnoteref-24)
The global operator delete(void*, std::size_t) precludes use of an
allocation function void operator new(std::size_t, std::size_t) as a placement
allocation function ([[diff.cpp11.basic]](diff.cpp11.basic "C.5.3[basic]: basics"))[.](#footnote-24.sentence-1)

View File

@@ -0,0 +1,40 @@
[basic.stc.auto]
# 6 Basics [[basic]](./#basic)
## 6.8 Memory and objects [[basic.memobj]](basic.memobj#basic.stc.auto)
### 6.8.6 Storage duration [[basic.stc]](basic.stc#auto)
#### 6.8.6.4 Automatic storage duration [basic.stc.auto]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4337)
Variables that belong to a block scope and are
not explicitly declared static, thread_local, or extern have[*automatic storage duration*](#def:storage_duration,automatic "6.8.6.4Automatic storage duration[basic.stc.auto]")[.](#1.sentence-1)
The storage
for such variables lasts until the block in which they are created exits[.](#1.sentence-2)
[*Note [1](#note-1)*:
These variables are initialized and destroyed as described in [[stmt.dcl]](stmt.dcl "8.10Declaration statement")[.](#1.sentence-3)
— *end note*]
Variables that belong to a parameter scope also have automatic storage duration[.](#1.sentence-4)
The storage for a function parameter lasts until
immediately after its destruction ([[expr.call]](expr.call "7.6.1.3Function call"))[.](#1.sentence-5)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4350)
If a variable with automatic storage duration has initialization or a destructor with side
effects, an implementation shall not destroy it before the end of its block
nor eliminate it as an optimization, even if it appears to be
unused, except that a class object or its copy/move may be eliminated as
specified in [[class.copy.elision]](class.copy.elision "11.9.6Copy/move elision")[.](#2.sentence-1)

View File

@@ -0,0 +1,326 @@
[basic.stc.dynamic]
# 6 Basics [[basic]](./#basic)
## 6.8 Memory and objects [[basic.memobj]](basic.memobj#basic.stc.dynamic)
### 6.8.6 Storage duration [[basic.stc]](basic.stc#dynamic)
#### 6.8.6.5 Dynamic storage duration [basic.stc.dynamic]
#### [6.8.6.5.1](#general) General [[basic.stc.dynamic.general]](basic.stc.dynamic.general)
[1](#general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4362)
Objects can be created dynamically during [program
execution](intro.execution "6.10.1Sequential execution[intro.execution]"), using[*new-expression*](expr.new#nt:new-expression "7.6.2.8New[expr.new]")*s* ([[expr.new]](expr.new "7.6.2.8New")), and destroyed using[*delete-expression*](expr.delete#nt:delete-expression "7.6.2.9Delete[expr.delete]")*s* ([[expr.delete]](expr.delete "7.6.2.9Delete"))[.](#general-1.sentence-1)
A C++ implementation
provides access to, and management of, dynamic storage via
the global [*allocation functions*](#def:allocation_function "6.8.6.5.1General[basic.stc.dynamic.general]")operator new andoperator new[] and
the global [*deallocation functions*](#def:deallocation_function "6.8.6.5.1General[basic.stc.dynamic.general]")operator delete andoperator delete[][.](#general-1.sentence-2)
[*Note [1](#general-note-1)*:
The non-allocating forms described in [[new.delete.placement]](new.delete.placement "17.6.3.4Non-allocating forms") do not perform allocation or deallocation[.](#general-1.sentence-3)
— *end note*]
[2](#general-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4381)
The library provides default definitions for the global allocation and
deallocation functions[.](#general-2.sentence-1)
Some global allocation and deallocation
functions are replaceable ([[dcl.fct.def.replace]](dcl.fct.def.replace#term.replaceable.function "9.6.5Replaceable function definitions"))[.](#general-2.sentence-2)
The following allocation and deallocation functions ([[support.dynamic]](support.dynamic "17.6Dynamic memory management"))
are implicitly declared in global scope in each translation unit of a
program[.](#general-2.sentence-3)
void* operator new(std::size_t);void* operator new(std::size_t, std::align_val_t);
void operator delete(void*) noexcept;void operator delete(void*, std::size_t) noexcept;void operator delete(void*, std::align_val_t) noexcept;void operator delete(void*, std::size_t, std::align_val_t) noexcept;
void* operator new[](std::size_t);void* operator new[](std::size_t, std::align_val_t);
void operator delete[](void*) noexcept;void operator delete[](void*, std::size_t) noexcept;void operator delete[](void*, std::align_val_t) noexcept;void operator delete[](void*, std::size_t, std::align_val_t) noexcept;
These implicit declarations introduce only the function namesoperator new,operator new[],operator delete, andoperator delete[][.](#general-2.sentence-4)
[*Note [2](#general-note-2)*:
The implicit declarations do not introduce
the names std,std::size_t,std::align_val_t,
or any other names that the library uses to
declare these names[.](#general-2.sentence-5)
Thus, a [*new-expression*](expr.new#nt:new-expression "7.6.2.8New[expr.new]"),[*delete-expression*](expr.delete#nt:delete-expression "7.6.2.9Delete[expr.delete]"), or function call that refers to one of
these functions without importing or including the header [<new>](support.dynamic.general#header:%3cnew%3e "17.6.1General[support.dynamic.general]") or importing a C++ library module ([[std.modules]](std.modules "16.4.2.4Modules"))
is well-formed[.](#general-2.sentence-6)
However, referring to std or std::size_t or std::align_val_t is ill-formed unless
a standard library declaration ([[cstddef.syn]](cstddef.syn "17.2.1Header <cstddef> synopsis"), [[new.syn]](new.syn "17.6.2Header <new> synopsis"), [[std.modules]](std.modules "16.4.2.4Modules"))
of that name precedes ([[basic.lookup.general]](basic.lookup.general "6.5.1General")) the use of that name[.](#general-2.sentence-7)
— *end note*]
Allocation and/or
deallocation functions may also be declared and defined for any
class ([[class.free]](class.free "11.4.11Allocation and deallocation functions"))[.](#general-2.sentence-8)
[3](#general-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4433)
If the behavior of an allocation or deallocation function
does not satisfy the semantic constraints
specified in [[basic.stc.dynamic.allocation]](#allocation "6.8.6.5.2Allocation functions") and [[basic.stc.dynamic.deallocation]](#deallocation "6.8.6.5.3Deallocation functions"),
the behavior is undefined[.](#general-3.sentence-1)
#### [6.8.6.5.2](#allocation) Allocation functions [[basic.stc.dynamic.allocation]](basic.stc.dynamic.allocation)
[1](#allocation-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4444)
An allocation function that is not a class member function
shall belong to the global scope and not have a name with internal linkage[.](#allocation-1.sentence-1)
The return type shall be void*[.](#allocation-1.sentence-2)
The first
parameter shall have type std::size_t ([[support.types]](support.types "17.2Common definitions"))[.](#allocation-1.sentence-3)
The
first parameter shall not have an associated default
argument ([[dcl.fct.default]](dcl.fct.default "9.3.4.7Default arguments"))[.](#allocation-1.sentence-4)
The value of the first parameter
is interpreted as the requested size of the allocation[.](#allocation-1.sentence-5)
An allocation
function can be a function template[.](#allocation-1.sentence-6)
Such a template shall declare its
return type and first parameter as specified above (that is, template
parameter types shall not be used in the return type and first parameter
type)[.](#allocation-1.sentence-7)
Allocation function templates shall have two or more parameters[.](#allocation-1.sentence-8)
[2](#allocation-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4458)
An allocation function attempts to allocate the requested amount of
storage[.](#allocation-2.sentence-1)
If it is successful, it returns the address of the start
of a block of storage whose length in bytes is at least as large
as the requested size[.](#allocation-2.sentence-2)
The order,
contiguity, and initial value of storage allocated by successive calls
to an allocation function are unspecified[.](#allocation-2.sentence-3)
Even if the size of the space
requested is zero, the request can fail[.](#allocation-2.sentence-4)
If the request succeeds, the
value returned by a replaceable allocation function
is a non-null pointer value ([[basic.compound]](basic.compound "6.9.4Compound types"))p0 different from any previously returned value p1,
unless that value p1 was subsequently passed to a
replaceable deallocation function[.](#allocation-2.sentence-5)
Furthermore, for the library allocation functions
in [[new.delete.single]](new.delete.single "17.6.3.2Single-object forms") and [[new.delete.array]](new.delete.array "17.6.3.3Array forms"),p0 represents the address of a block of storage disjoint from the storage
for any other object accessible to the caller[.](#allocation-2.sentence-6)
The effect of indirecting through a pointer
returned from a request for zero size is undefined[.](#allocation-2.sentence-7)[23](#footnote-23 "The intent is to have operator new() implementable by calling std::malloc() or std::calloc(), so the rules are substantially the same. C++ differs from C in requiring a zero request to return a non-null pointer.")
[3](#allocation-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4487)
For an allocation function other than
a reserved placement allocation function ([[new.delete.placement]](new.delete.placement "17.6.3.4Non-allocating forms")),
the pointer returned on a successful call
shall represent the address of storage that is aligned as follows:
- [(3.1)](#allocation-3.1)
If the allocation function takes an argument
of type std::align_val_t,
the storage will have the alignment specified
by the value of this argument[.](#allocation-3.1.sentence-1)
- [(3.2)](#allocation-3.2)
Otherwise, if the allocation function is named operator new[],
the storage is aligned for any object that
does not have new-extended alignment ([[basic.align]](basic.align "6.8.3Alignment")) and
is no larger than the requested size[.](#allocation-3.2.sentence-1)
- [(3.3)](#allocation-3.3)
Otherwise, the storage is aligned for any object that
does not have new-extended alignment and is of the requested size[.](#allocation-3.3.sentence-1)
[4](#allocation-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4508)
An allocation function that fails to allocate storage can invoke the
currently installed new-handler function ([[new.handler]](new.handler "17.6.4.3Type new_­handler")), if any[.](#allocation-4.sentence-1)
[*Note [1](#allocation-note-1)*:
A program-supplied allocation function can obtain the
currently installed new_handler using thestd::get_new_handler function ([[get.new.handler]](get.new.handler "17.6.4.5get_­new_­handler"))[.](#allocation-4.sentence-2)
— *end note*]
An allocation function that has a non-throwing
exception specification ([[except.spec]](except.spec "14.5Exception specifications"))
indicates failure by returning
a null pointer value[.](#allocation-4.sentence-3)
Any other allocation function
never returns a null pointer value and
indicates failure only by throwing an exception ([[except.throw]](except.throw "14.2Throwing an exception")) of a type
that would match a handler ([[except.handle]](except.handle "14.4Handling an exception")) of typestd::bad_alloc ([[bad.alloc]](bad.alloc "17.6.4.1Class bad_­alloc"))[.](#allocation-4.sentence-4)
[5](#allocation-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4527)
A global allocation function is only called as the result of a [new
expression](expr.new "7.6.2.8New[expr.new]"), or called directly using the [function call](expr.call "7.6.1.3Function call[expr.call]") syntax, or called indirectly to allocate storage for
a coroutine state ([[dcl.fct.def.coroutine]](dcl.fct.def.coroutine "9.6.4Coroutine definitions")),
or called indirectly through calls to the
functions in the C++ standard library[.](#allocation-5.sentence-1)
[*Note [2](#allocation-note-2)*:
In particular, a
global allocation function is not called to allocate storage
for objects with static storage duration ([[basic.stc.static]](basic.stc.static "6.8.6.2Static storage duration")),
for objects or references with thread storage duration ([[basic.stc.thread]](basic.stc.thread "6.8.6.3Thread storage duration")),
for objects of type std::type_info ([[expr.typeid]](expr.typeid "7.6.1.8Type identification")),
for an object of type std::contracts::contract_violation when a contract violation occurs ([[basic.contract.eval]](basic.contract.eval "6.11.2Evaluation")), or
for an exception object ([[except.throw]](except.throw "14.2Throwing an exception"))[.](#allocation-5.sentence-2)
— *end note*]
[23)](#footnote-23)[23)](#footnoteref-23)
The intent is
to have operator new() implementable by
calling std::malloc() or std::calloc(), so the rules are
substantially the same[.](#footnote-23.sentence-1)
C++ differs from C in requiring a zero request
to return a non-null pointer[.](#footnote-23.sentence-2)
#### [6.8.6.5.3](#deallocation) Deallocation functions [[basic.stc.dynamic.deallocation]](basic.stc.dynamic.deallocation)
[1](#deallocation-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4547)
A deallocation function that is not a class member function
shall belong to the global scope and not have a name with internal linkage[.](#deallocation-1.sentence-1)
[2](#deallocation-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4552)
A deallocation function
is a [*destroying operator delete*](#def:operator_delete,destroying "6.8.6.5.3Deallocation functions[basic.stc.dynamic.deallocation]") if it has at least two parameters
and its second parameter
is of type std::destroying_delete_t[.](#deallocation-2.sentence-1)
A destroying operator delete
shall be a class member function named operator delete[.](#deallocation-2.sentence-2)
[*Note [1](#deallocation-note-1)*:
Array deletion cannot use a destroying operator delete[.](#deallocation-2.sentence-3)
— *end note*]
[3](#deallocation-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4564)
Each deallocation function shall return void[.](#deallocation-3.sentence-1)
If the function is a destroying operator delete
declared in class type C,
the type of its first parameter shall be C*;
otherwise, the type of its first
parameter shall be void*[.](#deallocation-3.sentence-2)
A deallocation function may have more
than one parameter[.](#deallocation-3.sentence-3)
A [*usual deallocation function*](#def:usual_deallocation_function "6.8.6.5.3Deallocation functions[basic.stc.dynamic.deallocation]") is a deallocation function
whose parameters after the first are
- [(3.1)](#deallocation-3.1)
optionally, a parameter of type std::destroying_delete_t, then
- [(3.2)](#deallocation-3.2)
optionally, a parameter of type std::size_t,[24](#footnote-24 "The global operator delete(void*, std::size_­t) precludes use of an allocation function void operator new(std::size_­t, std::size_­t) as a placement allocation function ([diff.cpp11.basic]).") then
- [(3.3)](#deallocation-3.3)
optionally, a parameter of type std::align_val_t[.](#deallocation-3.sentence-4)
A destroying operator delete shall be a usual deallocation function[.](#deallocation-3.sentence-5)
A deallocation function may be an instance of a function
template[.](#deallocation-3.sentence-6)
Neither the first parameter nor the return type shall depend
on a template parameter[.](#deallocation-3.sentence-7)
A deallocation
function template shall have two or more function parameters[.](#deallocation-3.sentence-8)
A template
instance is never a usual deallocation function, regardless of its
signature[.](#deallocation-3.sentence-9)
[4](#deallocation-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4600)
If a deallocation function terminates by throwing an exception, the behavior is undefined[.](#deallocation-4.sentence-1)
The value of the first argument supplied to a deallocation function may
be a null pointer value; if so, and if the deallocation function is one
supplied in the standard library, the call has no effect[.](#deallocation-4.sentence-2)
[5](#deallocation-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4606)
If the argument given to a deallocation function in the standard library
is a pointer that is not the null pointer value ([[basic.compound]](basic.compound "6.9.4Compound types")), the
deallocation function shall deallocate the storage referenced by the
pointer, ending the duration of the region of storage[.](#deallocation-5.sentence-1)
[24)](#footnote-24)[24)](#footnoteref-24)
The global operator delete(void*, std::size_t) precludes use of an
allocation function void operator new(std::size_t, std::size_t) as a placement
allocation function ([[diff.cpp11.basic]](diff.cpp11.basic "C.5.3[basic]: basics"))[.](#footnote-24.sentence-1)

View File

@@ -0,0 +1,155 @@
[basic.stc.dynamic.allocation]
# 6 Basics [[basic]](./#basic)
## 6.8 Memory and objects [[basic.memobj]](basic.memobj#basic.stc.dynamic.allocation)
### 6.8.6 Storage duration [[basic.stc]](basic.stc#dynamic.allocation)
#### 6.8.6.5 Dynamic storage duration [[basic.stc.dynamic]](basic.stc.dynamic#allocation)
#### 6.8.6.5.2 Allocation functions [basic.stc.dynamic.allocation]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4444)
An allocation function that is not a class member function
shall belong to the global scope and not have a name with internal linkage[.](#1.sentence-1)
The return type shall be void*[.](#1.sentence-2)
The first
parameter shall have type std::size_t ([[support.types]](support.types "17.2Common definitions"))[.](#1.sentence-3)
The
first parameter shall not have an associated default
argument ([[dcl.fct.default]](dcl.fct.default "9.3.4.7Default arguments"))[.](#1.sentence-4)
The value of the first parameter
is interpreted as the requested size of the allocation[.](#1.sentence-5)
An allocation
function can be a function template[.](#1.sentence-6)
Such a template shall declare its
return type and first parameter as specified above (that is, template
parameter types shall not be used in the return type and first parameter
type)[.](#1.sentence-7)
Allocation function templates shall have two or more parameters[.](#1.sentence-8)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4458)
An allocation function attempts to allocate the requested amount of
storage[.](#2.sentence-1)
If it is successful, it returns the address of the start
of a block of storage whose length in bytes is at least as large
as the requested size[.](#2.sentence-2)
The order,
contiguity, and initial value of storage allocated by successive calls
to an allocation function are unspecified[.](#2.sentence-3)
Even if the size of the space
requested is zero, the request can fail[.](#2.sentence-4)
If the request succeeds, the
value returned by a replaceable allocation function
is a non-null pointer value ([[basic.compound]](basic.compound "6.9.4Compound types"))p0 different from any previously returned value p1,
unless that value p1 was subsequently passed to a
replaceable deallocation function[.](#2.sentence-5)
Furthermore, for the library allocation functions
in [[new.delete.single]](new.delete.single "17.6.3.2Single-object forms") and [[new.delete.array]](new.delete.array "17.6.3.3Array forms"),p0 represents the address of a block of storage disjoint from the storage
for any other object accessible to the caller[.](#2.sentence-6)
The effect of indirecting through a pointer
returned from a request for zero size is undefined[.](#2.sentence-7)[23](#footnote-23 "The intent is to have operator new() implementable by calling std::malloc() or std::calloc(), so the rules are substantially the same. C++ differs from C in requiring a zero request to return a non-null pointer.")
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4487)
For an allocation function other than
a reserved placement allocation function ([[new.delete.placement]](new.delete.placement "17.6.3.4Non-allocating forms")),
the pointer returned on a successful call
shall represent the address of storage that is aligned as follows:
- [(3.1)](#3.1)
If the allocation function takes an argument
of type std::align_val_t,
the storage will have the alignment specified
by the value of this argument[.](#3.1.sentence-1)
- [(3.2)](#3.2)
Otherwise, if the allocation function is named operator new[],
the storage is aligned for any object that
does not have new-extended alignment ([[basic.align]](basic.align "6.8.3Alignment")) and
is no larger than the requested size[.](#3.2.sentence-1)
- [(3.3)](#3.3)
Otherwise, the storage is aligned for any object that
does not have new-extended alignment and is of the requested size[.](#3.3.sentence-1)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4508)
An allocation function that fails to allocate storage can invoke the
currently installed new-handler function ([[new.handler]](new.handler "17.6.4.3Type new_­handler")), if any[.](#4.sentence-1)
[*Note [1](#note-1)*:
A program-supplied allocation function can obtain the
currently installed new_handler using thestd::get_new_handler function ([[get.new.handler]](get.new.handler "17.6.4.5get_­new_­handler"))[.](#4.sentence-2)
— *end note*]
An allocation function that has a non-throwing
exception specification ([[except.spec]](except.spec "14.5Exception specifications"))
indicates failure by returning
a null pointer value[.](#4.sentence-3)
Any other allocation function
never returns a null pointer value and
indicates failure only by throwing an exception ([[except.throw]](except.throw "14.2Throwing an exception")) of a type
that would match a handler ([[except.handle]](except.handle "14.4Handling an exception")) of typestd::bad_alloc ([[bad.alloc]](bad.alloc "17.6.4.1Class bad_­alloc"))[.](#4.sentence-4)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4527)
A global allocation function is only called as the result of a [new
expression](expr.new "7.6.2.8New[expr.new]"), or called directly using the [function call](expr.call "7.6.1.3Function call[expr.call]") syntax, or called indirectly to allocate storage for
a coroutine state ([[dcl.fct.def.coroutine]](dcl.fct.def.coroutine "9.6.4Coroutine definitions")),
or called indirectly through calls to the
functions in the C++ standard library[.](#5.sentence-1)
[*Note [2](#note-2)*:
In particular, a
global allocation function is not called to allocate storage
for objects with static storage duration ([[basic.stc.static]](basic.stc.static "6.8.6.2Static storage duration")),
for objects or references with thread storage duration ([[basic.stc.thread]](basic.stc.thread "6.8.6.3Thread storage duration")),
for objects of type std::type_info ([[expr.typeid]](expr.typeid "7.6.1.8Type identification")),
for an object of type std::contracts::contract_violation when a contract violation occurs ([[basic.contract.eval]](basic.contract.eval "6.11.2Evaluation")), or
for an exception object ([[except.throw]](except.throw "14.2Throwing an exception"))[.](#5.sentence-2)
— *end note*]
[23)](#footnote-23)[23)](#footnoteref-23)
The intent is
to have operator new() implementable by
calling std::malloc() or std::calloc(), so the rules are
substantially the same[.](#footnote-23.sentence-1)
C++ differs from C in requiring a zero request
to return a non-null pointer[.](#footnote-23.sentence-2)

View File

@@ -0,0 +1,106 @@
[basic.stc.dynamic.deallocation]
# 6 Basics [[basic]](./#basic)
## 6.8 Memory and objects [[basic.memobj]](basic.memobj#basic.stc.dynamic.deallocation)
### 6.8.6 Storage duration [[basic.stc]](basic.stc#dynamic.deallocation)
#### 6.8.6.5 Dynamic storage duration [[basic.stc.dynamic]](basic.stc.dynamic#deallocation)
#### 6.8.6.5.3 Deallocation functions [basic.stc.dynamic.deallocation]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4547)
A deallocation function that is not a class member function
shall belong to the global scope and not have a name with internal linkage[.](#1.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4552)
A deallocation function
is a [*destroying operator delete*](#def:operator_delete,destroying "6.8.6.5.3Deallocation functions[basic.stc.dynamic.deallocation]") if it has at least two parameters
and its second parameter
is of type std::destroying_delete_t[.](#2.sentence-1)
A destroying operator delete
shall be a class member function named operator delete[.](#2.sentence-2)
[*Note [1](#note-1)*:
Array deletion cannot use a destroying operator delete[.](#2.sentence-3)
— *end note*]
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4564)
Each deallocation function shall return void[.](#3.sentence-1)
If the function is a destroying operator delete
declared in class type C,
the type of its first parameter shall be C*;
otherwise, the type of its first
parameter shall be void*[.](#3.sentence-2)
A deallocation function may have more
than one parameter[.](#3.sentence-3)
A [*usual deallocation function*](#def:usual_deallocation_function "6.8.6.5.3Deallocation functions[basic.stc.dynamic.deallocation]") is a deallocation function
whose parameters after the first are
- [(3.1)](#3.1)
optionally, a parameter of type std::destroying_delete_t, then
- [(3.2)](#3.2)
optionally, a parameter of type std::size_t,[24](#footnote-24 "The global operator delete(void*, std::size_­t) precludes use of an allocation function void operator new(std::size_­t, std::size_­t) as a placement allocation function ([diff.cpp11.basic]).") then
- [(3.3)](#3.3)
optionally, a parameter of type std::align_val_t[.](#3.sentence-4)
A destroying operator delete shall be a usual deallocation function[.](#3.sentence-5)
A deallocation function may be an instance of a function
template[.](#3.sentence-6)
Neither the first parameter nor the return type shall depend
on a template parameter[.](#3.sentence-7)
A deallocation
function template shall have two or more function parameters[.](#3.sentence-8)
A template
instance is never a usual deallocation function, regardless of its
signature[.](#3.sentence-9)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4600)
If a deallocation function terminates by throwing an exception, the behavior is undefined[.](#4.sentence-1)
The value of the first argument supplied to a deallocation function may
be a null pointer value; if so, and if the deallocation function is one
supplied in the standard library, the call has no effect[.](#4.sentence-2)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4606)
If the argument given to a deallocation function in the standard library
is a pointer that is not the null pointer value ([[basic.compound]](basic.compound "6.9.4Compound types")), the
deallocation function shall deallocate the storage referenced by the
pointer, ending the duration of the region of storage[.](#5.sentence-1)
[24)](#footnote-24)[24)](#footnoteref-24)
The global operator delete(void*, std::size_t) precludes use of an
allocation function void operator new(std::size_t, std::size_t) as a placement
allocation function ([[diff.cpp11.basic]](diff.cpp11.basic "C.5.3[basic]: basics"))[.](#footnote-24.sentence-1)

View File

@@ -0,0 +1,83 @@
[basic.stc.dynamic.general]
# 6 Basics [[basic]](./#basic)
## 6.8 Memory and objects [[basic.memobj]](basic.memobj#basic.stc.dynamic.general)
### 6.8.6 Storage duration [[basic.stc]](basic.stc#dynamic.general)
#### 6.8.6.5 Dynamic storage duration [[basic.stc.dynamic]](basic.stc.dynamic#general)
#### 6.8.6.5.1 General [basic.stc.dynamic.general]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4362)
Objects can be created dynamically during [program
execution](intro.execution "6.10.1Sequential execution[intro.execution]"), using[*new-expression*](expr.new#nt:new-expression "7.6.2.8New[expr.new]")*s* ([[expr.new]](expr.new "7.6.2.8New")), and destroyed using[*delete-expression*](expr.delete#nt:delete-expression "7.6.2.9Delete[expr.delete]")*s* ([[expr.delete]](expr.delete "7.6.2.9Delete"))[.](#1.sentence-1)
A C++ implementation
provides access to, and management of, dynamic storage via
the global [*allocation functions*](#def:allocation_function "6.8.6.5.1General[basic.stc.dynamic.general]")operator new andoperator new[] and
the global [*deallocation functions*](#def:deallocation_function "6.8.6.5.1General[basic.stc.dynamic.general]")operator delete andoperator delete[][.](#1.sentence-2)
[*Note [1](#note-1)*:
The non-allocating forms described in [[new.delete.placement]](new.delete.placement "17.6.3.4Non-allocating forms") do not perform allocation or deallocation[.](#1.sentence-3)
— *end note*]
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4381)
The library provides default definitions for the global allocation and
deallocation functions[.](#2.sentence-1)
Some global allocation and deallocation
functions are replaceable ([[dcl.fct.def.replace]](dcl.fct.def.replace#term.replaceable.function "9.6.5Replaceable function definitions"))[.](#2.sentence-2)
The following allocation and deallocation functions ([[support.dynamic]](support.dynamic "17.6Dynamic memory management"))
are implicitly declared in global scope in each translation unit of a
program[.](#2.sentence-3)
void* operator new(std::size_t);void* operator new(std::size_t, std::align_val_t);
void operator delete(void*) noexcept;void operator delete(void*, std::size_t) noexcept;void operator delete(void*, std::align_val_t) noexcept;void operator delete(void*, std::size_t, std::align_val_t) noexcept;
void* operator new[](std::size_t);void* operator new[](std::size_t, std::align_val_t);
void operator delete[](void*) noexcept;void operator delete[](void*, std::size_t) noexcept;void operator delete[](void*, std::align_val_t) noexcept;void operator delete[](void*, std::size_t, std::align_val_t) noexcept;
These implicit declarations introduce only the function namesoperator new,operator new[],operator delete, andoperator delete[][.](#2.sentence-4)
[*Note [2](#note-2)*:
The implicit declarations do not introduce
the names std,std::size_t,std::align_val_t,
or any other names that the library uses to
declare these names[.](#2.sentence-5)
Thus, a [*new-expression*](expr.new#nt:new-expression "7.6.2.8New[expr.new]"),[*delete-expression*](expr.delete#nt:delete-expression "7.6.2.9Delete[expr.delete]"), or function call that refers to one of
these functions without importing or including the header [<new>](support.dynamic.general#header:%3cnew%3e "17.6.1General[support.dynamic.general]") or importing a C++ library module ([[std.modules]](std.modules "16.4.2.4Modules"))
is well-formed[.](#2.sentence-6)
However, referring to std or std::size_t or std::align_val_t is ill-formed unless
a standard library declaration ([[cstddef.syn]](cstddef.syn "17.2.1Header <cstddef> synopsis"), [[new.syn]](new.syn "17.6.2Header <new> synopsis"), [[std.modules]](std.modules "16.4.2.4Modules"))
of that name precedes ([[basic.lookup.general]](basic.lookup.general "6.5.1General")) the use of that name[.](#2.sentence-7)
— *end note*]
Allocation and/or
deallocation functions may also be declared and defined for any
class ([[class.free]](class.free "11.4.11Allocation and deallocation functions"))[.](#2.sentence-8)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4433)
If the behavior of an allocation or deallocation function
does not satisfy the semantic constraints
specified in [[basic.stc.dynamic.allocation]](basic.stc.dynamic.allocation "6.8.6.5.2Allocation functions") and [[basic.stc.dynamic.deallocation]](basic.stc.dynamic.deallocation "6.8.6.5.3Deallocation functions"),
the behavior is undefined[.](#3.sentence-1)

View File

@@ -0,0 +1,68 @@
[basic.stc.general]
# 6 Basics [[basic]](./#basic)
## 6.8 Memory and objects [[basic.memobj]](basic.memobj#basic.stc.general)
### 6.8.6 Storage duration [[basic.stc]](basic.stc#general)
#### 6.8.6.1 General [basic.stc.general]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4244)
The [*storage duration*](#def:storage_duration "6.8.6.1General[basic.stc.general]") is the property of an object that defines the minimum
potential lifetime of the storage containing the object[.](#1.sentence-1)
The storage
duration is determined by the construct used to create the object and is
one of the following:
- [(1.1)](#1.1)
static storage duration
- [(1.2)](#1.2)
thread storage duration
- [(1.3)](#1.3)
automatic storage duration
- [(1.4)](#1.4)
dynamic storage duration
[*Note [1](#note-1)*:
After the duration of a region of storage has ended,
the use of pointers to that region of storage is limited ([[basic.compound]](basic.compound "6.9.4Compound types"))[.](#1.sentence-2)
— *end note*]
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4261)
Static, thread, and automatic storage durations are associated with objects
introduced by declarations ([[basic.def]](basic.def "6.2Declarations and definitions")) and
with temporary objects ([[class.temporary]](class.temporary "6.8.7Temporary objects"))[.](#2.sentence-1)
The dynamic storage duration
is associated with objects created by a[*new-expression*](expr.new#nt:new-expression "7.6.2.8New[expr.new]") ([[expr.new]](expr.new "7.6.2.8New")) or
with implicitly created objects ([[intro.object]](intro.object "6.8.2Object model"))[.](#2.sentence-2)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4274)
The storage duration categories apply to references as well[.](#3.sentence-1)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4277)
The storage duration of subobjects and reference members
is that of their complete object ([[intro.object]](intro.object "6.8.2Object model"))[.](#4.sentence-1)

View File

@@ -0,0 +1,55 @@
[basic.stc.static]
# 6 Basics [[basic]](./#basic)
## 6.8 Memory and objects [[basic.memobj]](basic.memobj#basic.stc.static)
### 6.8.6 Storage duration [[basic.stc]](basic.stc#static)
#### 6.8.6.2 Static storage duration [basic.stc.static]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4285)
All variables which
- [(1.1)](#1.1)
do not have thread storage duration and
- [(1.2)](#1.2)
belong to a namespace scope ([[basic.scope.namespace]](basic.scope.namespace "6.4.6Namespace scope")) or
are first declared with
the static or extern keywords ([[dcl.stc]](dcl.stc "9.2.2Storage class specifiers"))
have [*static storage duration*](#def:storage_duration,static "6.8.6.2Static storage duration[basic.stc.static]")[.](#1.sentence-1)
The storage for these entities lasts for the duration of the
program ([[basic.start.static]](basic.start.static "6.10.3.2Static initialization"), [[basic.start.term]](basic.start.term "6.10.3.4Termination"))[.](#1.sentence-2)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4299)
If a 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/move may be
eliminated as specified in [[class.copy.elision]](class.copy.elision "11.9.6Copy/move elision")[.](#2.sentence-1)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4305)
[*Note [1](#note-1)*:
The keyword static can be used to declare
a block variable ([[basic.scope.block]](basic.scope.block "6.4.3Block scope")) with static storage duration;[[stmt.dcl]](stmt.dcl "8.10Declaration statement") and [[basic.start.term]](basic.start.term "6.10.3.4Termination") describe the
initialization and destruction of such variables[.](#3.sentence-1)
The keyword static applied to
a class data member in a class definition
gives the data member static storage duration ([[class.static.data]](class.static.data "11.4.9.3Static data members"))[.](#3.sentence-2)
— *end note*]

View File

@@ -0,0 +1,33 @@
[basic.stc.thread]
# 6 Basics [[basic]](./#basic)
## 6.8 Memory and objects [[basic.memobj]](basic.memobj#basic.stc.thread)
### 6.8.6 Storage duration [[basic.stc]](basic.stc#thread)
#### 6.8.6.3 Thread storage duration [basic.stc.thread]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4320)
All variables declared with the thread_local keyword have[*thread storage duration*](#def:storage_duration,thread "6.8.6.3Thread storage duration[basic.stc.thread]")[.](#1.sentence-1)
The storage for these entities lasts for the duration of
the thread in which they are created[.](#1.sentence-2)
There is a distinct object or reference
per thread, and use of the declared name refers to the entity associated with
the current thread[.](#1.sentence-3)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L4328)
[*Note [1](#note-1)*:
A variable with thread storage duration is initialized as specified
in [[basic.start.static]](basic.start.static "6.10.3.2Static initialization"), [[basic.start.dynamic]](basic.start.dynamic "6.10.3.3Dynamic initialization of non-block variables"), and [[stmt.dcl]](stmt.dcl "8.10Declaration statement") and, if constructed, is destroyed on thread exit ([[basic.start.term]](basic.start.term "6.10.3.4Termination"))[.](#2.sentence-1)
— *end note*]

2517
cppdraft/basic/string.md Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,79 @@
[basic.string.general]
# 27 Strings library [[strings]](./#strings)
## 27.4 String classes [[string.classes]](string.classes#basic.string.general)
### 27.4.3 Class template basic_string [[basic.string]](basic.string#general)
#### 27.4.3.1 General [basic.string.general]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L1994)
The
class templatebasic_string describes objects that can store a sequence consisting of a varying number of
arbitrary char-like objects with the first element of the sequence at position zero[.](#1.sentence-1)
Such a sequence is also called a “string” if the type of the
char-like objects that it holds
is clear from context[.](#1.sentence-2)
In the rest of [[basic.string]](basic.string "27.4.3Class template basic_­string"),
the type of the char-like objects held in a basic_string object
is designated by charT[.](#1.sentence-3)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2008)
A specialization of basic_string is a contiguous container ([[container.reqmts]](container.reqmts "23.2.2.2Container requirements"))[.](#2.sentence-1)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2011)
In all cases,
[data(), data() + size()] is a valid range,data() + size() points at an object with value charT() (a “null terminator”),
and size() <= capacity() is true[.](#3.sentence-1)
[🔗](#lib:basic_string_)
namespace std {template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>class basic_string {public:// typesusing traits_type = traits; using value_type = charT; using allocator_type = Allocator; using size_type = typename allocator_traits<Allocator>::size_type; using difference_type = typename allocator_traits<Allocator>::difference_type; using pointer = typename allocator_traits<Allocator>::pointer; using const_pointer = typename allocator_traits<Allocator>::const_pointer; using reference = value_type&; using const_reference = const value_type&; using iterator = *implementation-defined*; // see [[container.requirements]](container.requirements "23.2Requirements")using const_iterator = *implementation-defined*; // see [[container.requirements]](container.requirements "23.2Requirements")using reverse_iterator = std::reverse_iterator<iterator>; using const_reverse_iterator = std::reverse_iterator<const_iterator>; static constexpr size_type npos = size_type(-1); // [[string.cons]](string.cons "27.4.3.3Constructors and assignment operators"), construct/copy/destroyconstexpr basic_string() noexcept(noexcept(Allocator())) : basic_string(Allocator()) { }constexpr explicit basic_string(const Allocator& a) noexcept; constexpr basic_string(const basic_string& str); constexpr basic_string(basic_string&& str) noexcept; constexpr basic_string(const basic_string& str, size_type pos, const Allocator& a = Allocator()); constexpr basic_string(const basic_string& str, size_type pos, size_type n, const Allocator& a = Allocator()); constexpr basic_string(basic_string&& str, size_type pos, const Allocator& a = Allocator()); constexpr basic_string(basic_string&& str, size_type pos, size_type n, const Allocator& a = Allocator()); template<class T>constexpr basic_string(const T& t, size_type pos, size_type n, const Allocator& a = Allocator()); template<class T>constexpr explicit basic_string(const T& t, const Allocator& a = Allocator()); constexpr basic_string(const charT* s, size_type n, const Allocator& a = Allocator()); constexpr basic_string(const charT* s, const Allocator& a = Allocator());
basic_string(nullptr_t) = delete; constexpr basic_string(size_type n, charT c, const Allocator& a = Allocator()); template<class InputIterator>constexpr basic_string(InputIterator begin, InputIterator end, const Allocator& a = Allocator()); template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1Introduction[container.intro.reqmts]")<charT> R>constexpr basic_string(from_range_t, R&& rg, const Allocator& a = Allocator()); constexpr basic_string(initializer_list<charT>, const Allocator& = Allocator()); constexpr basic_string(const basic_string&, const Allocator&); constexpr basic_string(basic_string&&, const Allocator&); constexpr ~basic_string(); constexpr basic_string& operator=(const basic_string& str); constexpr basic_string& operator=(basic_string&& str)noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value || allocator_traits<Allocator>::is_always_equal::value); template<class T>constexpr basic_string& operator=(const T& t); constexpr basic_string& operator=(const charT* s);
basic_string& operator=(nullptr_t) = delete; constexpr basic_string& operator=(charT c); constexpr basic_string& operator=(initializer_list<charT>); // [[string.iterators]](string.iterators "27.4.3.4Iterator support"), iteratorsconstexpr iterator begin() noexcept; constexpr const_iterator begin() const noexcept; constexpr iterator end() noexcept; constexpr const_iterator end() const noexcept; constexpr reverse_iterator rbegin() noexcept; constexpr const_reverse_iterator rbegin() const noexcept; constexpr reverse_iterator rend() noexcept; constexpr const_reverse_iterator rend() const noexcept; constexpr const_iterator cbegin() const noexcept; constexpr const_iterator cend() const noexcept; constexpr const_reverse_iterator crbegin() const noexcept; constexpr const_reverse_iterator crend() const noexcept; // [[string.capacity]](string.capacity "27.4.3.5Capacity"), capacityconstexpr size_type size() const noexcept; constexpr size_type length() const noexcept; constexpr size_type max_size() const noexcept; constexpr void resize(size_type n, charT c); constexpr void resize(size_type n); template<class Operation> constexpr void resize_and_overwrite(size_type n, Operation op); constexpr size_type capacity() const noexcept; constexpr void reserve(size_type res_arg); constexpr void shrink_to_fit(); constexpr void clear() noexcept; constexpr bool empty() const noexcept; // [[string.access]](string.access "27.4.3.6Element access"), element accessconstexpr const_reference operator[](size_type pos) const; constexpr reference operator[](size_type pos); constexpr const_reference at(size_type n) const; constexpr reference at(size_type n); constexpr const charT& front() const; constexpr charT& front(); constexpr const charT& back() const; constexpr charT& back(); // [[string.modifiers]](string.modifiers "27.4.3.7Modifiers"), modifiersconstexpr basic_string& operator+=(const basic_string& str); template<class T>constexpr basic_string& operator+=(const T& t); constexpr basic_string& operator+=(const charT* s); constexpr basic_string& operator+=(charT c); constexpr basic_string& operator+=(initializer_list<charT>); constexpr basic_string& append(const basic_string& str); constexpr basic_string& append(const basic_string& str, size_type pos, size_type n = npos); template<class T>constexpr basic_string& append(const T& t); template<class T>constexpr basic_string& append(const T& t, size_type pos, size_type n = npos); constexpr basic_string& append(const charT* s, size_type n); constexpr basic_string& append(const charT* s); constexpr basic_string& append(size_type n, charT c); template<class InputIterator>constexpr basic_string& append(InputIterator first, InputIterator last); template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1Introduction[container.intro.reqmts]")<charT> R>constexpr basic_string& append_range(R&& rg); constexpr basic_string& append(initializer_list<charT>); constexpr void push_back(charT c); constexpr basic_string& assign(const basic_string& str); constexpr basic_string& assign(basic_string&& str)noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value || allocator_traits<Allocator>::is_always_equal::value); constexpr basic_string& assign(const basic_string& str, size_type pos, size_type n = npos); template<class T>constexpr basic_string& assign(const T& t); template<class T>constexpr basic_string& assign(const T& t, size_type pos, size_type n = npos); constexpr basic_string& assign(const charT* s, size_type n); constexpr basic_string& assign(const charT* s); constexpr basic_string& assign(size_type n, charT c); template<class InputIterator>constexpr basic_string& assign(InputIterator first, InputIterator last); template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1Introduction[container.intro.reqmts]")<charT> R>constexpr basic_string& assign_range(R&& rg); constexpr basic_string& assign(initializer_list<charT>); constexpr basic_string& insert(size_type pos, const basic_string& str); constexpr basic_string& insert(size_type pos1, const basic_string& str,
size_type pos2, size_type n = npos); template<class T>constexpr basic_string& insert(size_type pos, const T& t); template<class T>constexpr basic_string& insert(size_type pos1, const T& t,
size_type pos2, size_type n = npos); constexpr basic_string& insert(size_type pos, const charT* s, size_type n); constexpr basic_string& insert(size_type pos, const charT* s); constexpr basic_string& insert(size_type pos, size_type n, charT c); constexpr iterator insert(const_iterator p, charT c); constexpr iterator insert(const_iterator p, size_type n, charT c); template<class InputIterator>constexpr iterator insert(const_iterator p, InputIterator first, InputIterator last); template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1Introduction[container.intro.reqmts]")<charT> R>constexpr iterator insert_range(const_iterator p, R&& rg); constexpr iterator insert(const_iterator p, initializer_list<charT>); constexpr basic_string& erase(size_type pos = 0, size_type n = npos); constexpr iterator erase(const_iterator p); constexpr iterator erase(const_iterator first, const_iterator last); constexpr void pop_back(); constexpr basic_string& replace(size_type pos1, size_type n1, const basic_string& str); constexpr basic_string& replace(size_type pos1, size_type n1, const basic_string& str,
size_type pos2, size_type n2 = npos); template<class T>constexpr basic_string& replace(size_type pos1, size_type n1, const T& t); template<class T>constexpr basic_string& replace(size_type pos1, size_type n1, const T& t,
size_type pos2, size_type n2 = npos); constexpr basic_string& replace(size_type pos, size_type n1, const charT* s, size_type n2); constexpr basic_string& replace(size_type pos, size_type n1, const charT* s); constexpr basic_string& replace(size_type pos, size_type n1, size_type n2, charT c); constexpr basic_string& replace(const_iterator i1, const_iterator i2, const basic_string& str); template<class T>constexpr basic_string& replace(const_iterator i1, const_iterator i2, const T& t); constexpr basic_string& replace(const_iterator i1, const_iterator i2, const charT* s,
size_type n); constexpr basic_string& replace(const_iterator i1, const_iterator i2, const charT* s); constexpr basic_string& replace(const_iterator i1, const_iterator i2, size_type n, charT c); template<class InputIterator>constexpr basic_string& replace(const_iterator i1, const_iterator i2,
InputIterator j1, InputIterator j2); template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1Introduction[container.intro.reqmts]")<charT> R>constexpr basic_string& replace_with_range(const_iterator i1, const_iterator i2, R&& rg); constexpr basic_string& replace(const_iterator, const_iterator, initializer_list<charT>); constexpr size_type copy(charT* s, size_type n, size_type pos = 0) const; constexpr void swap(basic_string& str)noexcept(allocator_traits<Allocator>::propagate_on_container_swap::value || allocator_traits<Allocator>::is_always_equal::value); // [[string.ops]](string.ops "27.4.3.8String operations"), string operationsconstexpr const charT* c_str() const noexcept; constexpr const charT* data() const noexcept; constexpr charT* data() noexcept; constexpr operator basic_string_view<charT, traits>() const noexcept; constexpr allocator_type get_allocator() const noexcept; template<class T>constexpr size_type find(const T& t, size_type pos = 0) const noexcept(*see below*); constexpr size_type find(const basic_string& str, size_type pos = 0) const noexcept; constexpr size_type find(const charT* s, size_type pos, size_type n) const; constexpr size_type find(const charT* s, size_type pos = 0) const; constexpr size_type find(charT c, size_type pos = 0) const noexcept; template<class T>constexpr size_type rfind(const T& t, size_type pos = npos) const noexcept(*see below*); constexpr size_type rfind(const basic_string& str, size_type pos = npos) const noexcept; constexpr size_type rfind(const charT* s, size_type pos, size_type n) const; constexpr size_type rfind(const charT* s, size_type pos = npos) const; constexpr size_type rfind(charT c, size_type pos = npos) const noexcept; template<class T>constexpr size_type find_first_of(const T& t, size_type pos = 0) const noexcept(*see below*); constexpr size_type find_first_of(const basic_string& str, size_type pos = 0) const noexcept; constexpr size_type find_first_of(const charT* s, size_type pos, size_type n) const; constexpr size_type find_first_of(const charT* s, size_type pos = 0) const; constexpr size_type find_first_of(charT c, size_type pos = 0) const noexcept; template<class T>constexpr size_type find_last_of(const T& t,
size_type pos = npos) const noexcept(*see below*); constexpr size_type find_last_of(const basic_string& str,
size_type pos = npos) const noexcept; constexpr size_type find_last_of(const charT* s, size_type pos, size_type n) const; constexpr size_type find_last_of(const charT* s, size_type pos = npos) const; constexpr size_type find_last_of(charT c, size_type pos = npos) const noexcept; template<class T>constexpr size_type find_first_not_of(const T& t,
size_type pos = 0) const noexcept(*see below*); constexpr size_type find_first_not_of(const basic_string& str,
size_type pos = 0) const noexcept; constexpr size_type find_first_not_of(const charT* s, size_type pos, size_type n) const; constexpr size_type find_first_not_of(const charT* s, size_type pos = 0) const; constexpr size_type find_first_not_of(charT c, size_type pos = 0) const noexcept; template<class T>constexpr size_type find_last_not_of(const T& t,
size_type pos = npos) const noexcept(*see below*); constexpr size_type find_last_not_of(const basic_string& str,
size_type pos = npos) const noexcept; constexpr size_type find_last_not_of(const charT* s, size_type pos, size_type n) const; constexpr size_type find_last_not_of(const charT* s, size_type pos = npos) const; constexpr size_type find_last_not_of(charT c, size_type pos = npos) const noexcept; constexpr basic_string substr(size_type pos = 0, size_type n = npos) const &; constexpr basic_string substr(size_type pos = 0, size_type n = npos) &&; constexpr basic_string_view<charT, traits> subview(size_type pos = 0,
size_type n = npos) const; template<class T>constexpr int compare(const T& t) const noexcept(*see below*); template<class T>constexpr int compare(size_type pos1, size_type n1, const T& t) const; template<class T>constexpr int compare(size_type pos1, size_type n1, const T& t,
size_type pos2, size_type n2 = npos) const; constexpr int compare(const basic_string& str) const noexcept; constexpr int compare(size_type pos1, size_type n1, const basic_string& str) const; constexpr int compare(size_type pos1, size_type n1, const basic_string& str,
size_type pos2, size_type n2 = npos) const; constexpr int compare(const charT* s) const; constexpr int compare(size_type pos1, size_type n1, const charT* s) const; constexpr int compare(size_type pos1, size_type n1, const charT* s, size_type n2) const; constexpr bool starts_with(basic_string_view<charT, traits> x) const noexcept; constexpr bool starts_with(charT x) const noexcept; constexpr bool starts_with(const charT* x) const; constexpr bool ends_with(basic_string_view<charT, traits> x) const noexcept; constexpr bool ends_with(charT x) const noexcept; constexpr bool ends_with(const charT* x) const; constexpr bool contains(basic_string_view<charT, traits> x) const noexcept; constexpr bool contains(charT x) const noexcept; constexpr bool contains(const charT* x) const; }; template<class InputIterator, class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>> basic_string(InputIterator, InputIterator, Allocator = Allocator())-> basic_string<typename iterator_traits<InputIterator>::value_type,
char_traits<typename iterator_traits<InputIterator>::value_type>,
Allocator>; template<ranges::[input_range](range.refinements#concept:input_range "25.4.6Other range refinements[range.refinements]") R, class Allocator = allocator<ranges::range_value_t<R>>> basic_string(from_range_t, R&&, Allocator = Allocator())-> basic_string<ranges::range_value_t<R>, char_traits<ranges::range_value_t<R>>,
Allocator>; template<class charT, class traits, class Allocator = allocator<charT>>explicit basic_string(basic_string_view<charT, traits>, const Allocator& = Allocator())-> basic_string<charT, traits, Allocator>; template<class charT, class traits, class Allocator = allocator<charT>> basic_string(basic_string_view<charT, traits>, typename *see below*::size_type, typename *see below*::size_type, const Allocator& = Allocator())-> basic_string<charT, traits, Allocator>;}
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2351)
A size_type parameter type in
a basic_string deduction guide
refers to the size_type member type of
the type deduced by the deduction guide[.](#4.sentence-1)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L2357)
The types iterator and const_iterator meet
the constexpr iterator requirements ([[iterator.requirements.general]](iterator.requirements.general "24.3.1General"))[.](#5.sentence-1)

View File

@@ -0,0 +1,23 @@
[basic.string.hash]
# 27 Strings library [[strings]](./#strings)
## 27.4 String classes [[string.classes]](string.classes#basic.string.hash)
### 27.4.6 Hash support [basic.string.hash]
[🔗](#lib:hash,basic_string)
`template<class A> struct hash<basic_string<char, char_traits<char>, A>>;
template<class A> struct hash<basic_string<char8_t, char_traits<char8_t>, A>>;
template<class A> struct hash<basic_string<char16_t, char_traits<char16_t>, A>>;
template<class A> struct hash<basic_string<char32_t, char_traits<char32_t>, A>>;
template<class A> struct hash<basic_string<wchar_t, char_traits<wchar_t>, A>>;
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5392)
If S is one of these string types,SV is the corresponding string view type, ands is an object of type S,
then hash<S>()(s) == hash<SV>()(SV(s))[.](#1.sentence-1)

View File

@@ -0,0 +1,72 @@
[basic.string.literals]
# 27 Strings library [[strings]](./#strings)
## 27.4 String classes [[string.classes]](string.classes#basic.string.literals)
### 27.4.7 Suffix for basic_string literals [basic.string.literals]
[🔗](#lib:operator%22%22s,string)
`constexpr string operator""s(const char* str, size_t len);
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5407)
*Returns*: string{str, len}[.](#1.sentence-1)
[🔗](#lib:operator%22%22s,u8string)
`constexpr u8string operator""s(const char8_t* str, size_t len);
`
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5417)
*Returns*: u8string{str, len}[.](#2.sentence-1)
[🔗](#lib:operator%22%22s,u16string)
`constexpr u16string operator""s(const char16_t* str, size_t len);
`
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5427)
*Returns*: u16string{str, len}[.](#3.sentence-1)
[🔗](#lib:operator%22%22s,u32string)
`constexpr u32string operator""s(const char32_t* str, size_t len);
`
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5437)
*Returns*: u32string{str, len}[.](#4.sentence-1)
[🔗](#lib:operator%22%22s,wstring)
`constexpr wstring operator""s(const wchar_t* str, size_t len);
`
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5447)
*Returns*: wstring{str, len}[.](#5.sentence-1)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5452)
[*Note [1](#note-1)*:
The same suffix s is used for chrono::duration literals denoting seconds but there is no conflict, since duration suffixes apply to numbers and string literal suffixes apply to character array literals[.](#6.sentence-1)
— *end note*]

View File

@@ -0,0 +1,139 @@
[basic.type.qualifier]
# 6 Basics [[basic]](./#basic)
## 6.9 Types [[basic.types]](basic.types#basic.type.qualifier)
### 6.9.5 CV-qualifiers [basic.type.qualifier]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5991)
Each type other than a function or reference type
is part of a group of four distinct, but related, types:
a [*cv-unqualified*](#def:cv-unqualified "6.9.5CV-qualifiers[basic.type.qualifier]") version,
a [*const-qualified*](#def:const-qualified "6.9.5CV-qualifiers[basic.type.qualifier]") version,
a [*volatile-qualified*](#def:volatile-qualified "6.9.5CV-qualifiers[basic.type.qualifier]") version, and
a [*const-volatile-qualified*](#def:const-volatile-qualified "6.9.5CV-qualifiers[basic.type.qualifier]") version[.](#1.sentence-1)
The types in each such group shall have
the same representation and alignment requirements ([[basic.align]](basic.align "6.8.3Alignment"))[.](#1.sentence-2)[34](#footnote-34 "The same representation and alignment requirements are meant to imply interchangeability as arguments to functions, return values from functions, and non-static data members of unions.")
A function or reference type is always cv-unqualified[.](#1.sentence-3)
- [(1.1)](#1.1)
A [*const object*](#def:object,const "6.9.5CV-qualifiers[basic.type.qualifier]") is an object of type const T or a
non-mutable subobject of a const object[.](#1.1.sentence-1)
- [(1.2)](#1.2)
A [*volatile object*](#def:object,volatile "6.9.5CV-qualifiers[basic.type.qualifier]") is an object of type volatile T or a subobject of a volatile object[.](#1.2.sentence-1)
- [(1.3)](#1.3)
A [*const volatile object*](#def:object,const_volatile "6.9.5CV-qualifiers[basic.type.qualifier]") is an object of type const volatile T, a non-mutable subobject of a const volatile object,
a const subobject of a volatile object, or a non-mutable volatile
subobject of a const object[.](#1.3.sentence-1)
[*Note [1](#note-1)*:
The type of an object ([[intro.object]](intro.object "6.8.2Object model")) includes
the [*cv-qualifier*](dcl.decl.general#nt:cv-qualifier "9.3.1General[dcl.decl.general]")*s* specified in the[*decl-specifier-seq*](dcl.spec.general#nt:decl-specifier-seq "9.2.1General[dcl.spec.general]") ([[dcl.spec]](dcl.spec "9.2Specifiers")),[*declarator*](dcl.decl.general#nt:declarator "9.3.1General[dcl.decl.general]") ([[dcl.decl]](dcl.decl "9.3Declarators")),[*type-id*](dcl.name#nt:type-id "9.3.2Type names[dcl.name]") ([[dcl.name]](dcl.name "9.3.2Type names")), or[*new-type-id*](expr.new#nt:new-type-id "7.6.2.8New[expr.new]") ([[expr.new]](expr.new "7.6.2.8New"))
when the object is created[.](#1.sentence-4)
— *end note*]
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6033)
Except for array types, a compound type ([[basic.compound]](basic.compound "6.9.4Compound types")) is not cv-qualified by the
cv-qualifiers (if any) of the types from which it is compounded[.](#2.sentence-1)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6037)
An array type whose elements are cv-qualified
is also considered to have the same cv-qualifications
as its elements[.](#3.sentence-1)
[*Note [2](#note-2)*:
Cv-qualifiers applied to an array
type attach to the underlying element type, so the notation
“cv T”, where T is an array type, refers to
an array whose elements are so-qualified ([[dcl.array]](dcl.array "9.3.4.5Arrays"))[.](#3.sentence-2)
— *end note*]
[*Example [1](#example-1)*: typedef char CA[5];typedef const char CC;
CC arr1[5] = { 0 };const CA arr2 = { 0 };
The type of both arr1 and arr2 is “array of 5const char”, and the array type is considered to be
const-qualified[.](#3.sentence-3)
— *end example*]
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6061)
[*Note [3](#note-3)*:
See [[dcl.fct]](dcl.fct "9.3.4.6Functions") and [[over.match.funcs]](over.match.funcs "12.2.2Candidate functions and argument lists") regarding function
types that have [*cv-qualifier*](dcl.decl.general#nt:cv-qualifier "9.3.1General[dcl.decl.general]")*s*[.](#4.sentence-1)
— *end note*]
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6067)
There is a partial ordering on cv-qualifiers, so that a type can be
said to be [*more cv-qualified*](#def:more_cv-qualified "6.9.5CV-qualifiers[basic.type.qualifier]") than another[.](#5.sentence-1)
Table [16](#tab:basic.type.qualifier.rel "Table 16: Relations on const and volatile") shows the relations that
constitute this ordering[.](#5.sentence-2)
Table [16](#tab:basic.type.qualifier.rel) — Relations on const and volatile [[tab:basic.type.qualifier.rel]](./tab:basic.type.qualifier.rel)
| [🔗](#tab:basic.type.qualifier.rel-row-1)<br>*no cv-qualifier* | < | const |
| --- | --- | --- |
| [🔗](#tab:basic.type.qualifier.rel-row-2)<br>*no cv-qualifier* | < | volatile |
| [🔗](#tab:basic.type.qualifier.rel-row-3)<br>*no cv-qualifier* | < | const volatile |
| [🔗](#tab:basic.type.qualifier.rel-row-4)<br>const | < | const volatile |
| [🔗](#tab:basic.type.qualifier.rel-row-5)<br>volatile | < | const volatile |
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L6083)
In this document, the notation cv (or*cv1*, *cv2*, etc[.](#6.sentence-1))
, used in the description of types,
represents an arbitrary set of cv-qualifiers, i.e., one of
{const}, {volatile}, {const,volatile}, or the empty set[.](#6.sentence-2)
For a type cv T, the [*top-level cv-qualifiers*](#def:cv-qualifier,top-level "6.9.5CV-qualifiers[basic.type.qualifier]") of that type are those denoted by cv[.](#6.sentence-3)
[*Example [2](#example-2)*:
The type corresponding to the [*type-id*](dcl.name#nt:type-id "9.3.2Type names[dcl.name]")const int& has no top-level cv-qualifiers[.](#6.sentence-4)
The type corresponding to the [*type-id*](dcl.name#nt:type-id "9.3.2Type names[dcl.name]")volatile int * const has the top-level cv-qualifier const[.](#6.sentence-5)
For a class type C,
the type corresponding to the [*type-id*](dcl.name#nt:type-id "9.3.2Type names[dcl.name]")void (C::* volatile)(int) const has the top-level cv-qualifier volatile[.](#6.sentence-6)
— *end example*]
[34)](#footnote-34)[34)](#footnoteref-34)
The same representation and alignment requirements
are meant to imply interchangeability as
arguments to functions,
return values from functions, and
non-static data members of unions[.](#footnote-34.sentence-1)

1453
cppdraft/basic/types.md Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,302 @@
[basic.types.general]
# 6 Basics [[basic]](./#basic)
## 6.9 Types [[basic.types]](basic.types#general)
### 6.9.1 General [basic.types.general]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5030)
[*Note [1](#note-1)*:
[[basic.types]](basic.types "6.9Types") and the subclauses thereof
impose requirements on implementations regarding the representation
of types[.](#1.sentence-1)
There are two kinds of types: fundamental types and compound types[.](#1.sentence-2)
Types describe [objects](intro.object "6.8.2Object model[intro.object]"),[references](dcl.ref "9.3.4.3References[dcl.ref]"),
or [functions](dcl.fct "9.3.4.6Functions[dcl.fct]")[.](#1.sentence-3)
— *end note*]
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5041)
For any object (other than a potentially-overlapping subobject) of trivially copyable typeT, whether or not the object holds a valid value of typeT, the underlying bytes ([[intro.memory]](intro.memory "6.8.1Memory model")) making up the
object can be copied into an array ofchar,unsigned char, orstd::byte ([[cstddef.syn]](cstddef.syn "17.2.1Header <cstddef> synopsis"))[.](#2.sentence-1)[26](#footnote-26 "By using, for example, the library functions ([headers]) std::memcpy or std::memmove.")
If the content of that array
is copied back into the object, the object shall
subsequently hold its original value[.](#2.sentence-2)
[*Example [1](#example-1)*: constexpr std::size_t N = sizeof(T);char buf[N];
T obj; // obj initialized to its original value std::memcpy(buf, &obj, N); // between these two calls to std::memcpy, obj might be modified std::memcpy(&obj, buf, N); // at this point, each subobject of obj of scalar type holds its original value — *end example*]
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5068)
For two distinct objects obj1 and obj2 of trivially copyable type T,
where neither obj1 nor obj2 is a potentially-overlapping subobject,
if the underlying bytes ([[intro.memory]](intro.memory "6.8.1Memory model")) making upobj1 are copied into obj2,[27](#footnote-27 "By using, for example, the library functions ([headers]) std::memcpy or std::memmove.")obj2 shall subsequently hold the same value asobj1[.](#3.sentence-1)
[*Example [2](#example-2)*: T* t1p;
T* t2p; // provided that t2p points to an initialized object ... std::memcpy(t1p, t2p, sizeof(T)); // at this point, every subobject of trivially copyable type in *t1p contains// the same value as the corresponding subobject in *t2p — *end example*]
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5092)
The [*object representation*](#def:representation,object "6.9.1General[basic.types.general]") of a complete object type T is the
sequence of *N* unsigned char objects taken up
by a non-bit-field complete object of type T,
where *N* equalssizeof(T)[.](#4.sentence-1)
The [*value representation*](#def:representation,value "6.9.1General[basic.types.general]") of a type T is the set of bits
in the object representation of T that participate in representing a value of type T[.](#4.sentence-2)
The object and value representation of
a non-bit-field complete object of type T are
the bytes and bits, respectively, of
the object corresponding to the object and value representation of its type[.](#4.sentence-3)
The object representation of a bit-field object is
the sequence of *N* bits taken up by the object,
where *N* is the width of the bit-field ([[class.bit]](class.bit "11.4.10Bit-fields"))[.](#4.sentence-4)
The value representation of a bit-field object is
the set of bits in the object representation that
participate in representing its value[.](#4.sentence-5)
Bits in the object representation of a type or object that are
not part of the value representation
are [*padding bits*](#def:padding_bits "6.9.1General[basic.types.general]")[.](#4.sentence-6)
For trivially copyable types, the value representation is
a set of bits in the object representation that determines a[*value*](#def:value "6.9.1General[basic.types.general]"), which is one discrete element of animplementation-defined set of values[.](#4.sentence-7)[28](#footnote-28 "The intent is that the memory model of C++ is compatible with that of the C programming language.")
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5127)
A class that has been declared but not defined, an enumeration type in certain
contexts ([[dcl.enum]](dcl.enum "9.8.1Enumeration declarations")), or an array of unknown
bound or of incomplete element type, is an[*incompletely-defined object type*](#def:object_type,incompletely-defined "6.9.1General[basic.types.general]")[.](#5.sentence-1)[29](#footnote-29 "The size and layout of an instance of an incompletely-defined object type is unknown.")
Incompletely-defined object types and cv void are[*incomplete types*](#def:type,incomplete "6.9.1General[basic.types.general]") ([[basic.fundamental]](basic.fundamental "6.9.2Fundamental types"))[.](#5.sentence-2)
[*Note [2](#note-2)*:
Objects cannot be defined to have an incomplete type ([[basic.def]](basic.def "6.2Declarations and definitions"))[.](#5.sentence-3)
— *end note*]
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5144)
A class type (such as “class X”) can be incomplete at one
point in a translation unit and complete later on; the type
“class X” is the same type at both points[.](#6.sentence-1)
The declared type
of an array object can be an array of incomplete class type and
therefore incomplete; if the class type is completed later on in the
translation unit, the array type becomes complete; the array type at
those two points is the same type[.](#6.sentence-2)
The declared type of an array object
can be an array of unknown bound and therefore be incomplete at one
point in a translation unit and complete later on; the array types at
those two points (“array of unknown bound of T” and “array ofN T”) are different types[.](#6.sentence-3)
[*Note [3](#note-3)*:
The type of a pointer or reference to array of unknown bound
permanently points to or refers to an incomplete type[.](#6.sentence-4)
An array of unknown bound named by a typedef declaration
permanently refers to an incomplete type[.](#6.sentence-5)
In either case, the array type cannot be completed[.](#6.sentence-6)
— *end note*]
[*Example [3](#example-3)*:
[🔗](#:type,example_of_incomplete)
class X; // X is an incomplete typeextern X* xp; // xp is a pointer to an incomplete typeextern int arr[]; // the type of arr is incompletetypedef int UNKA[]; // UNKA is an incomplete type UNKA* arrp; // arrp is a pointer to an incomplete type UNKA** arrpp;
void foo() { xp++; // error: X is incomplete arrp++; // error: incomplete type arrpp++; // OK, sizeof UNKA* is known}struct X { int i; }; // now X is a complete typeint arr[10]; // now the type of arr is complete X x;void bar() { xp = &x; // OK; type is “pointer to X'' arrp = &arr; // OK; qualification conversion ([[conv.qual]](conv.qual "7.3.6Qualification conversions")) xp++; // OK, X is complete arrp++; // error: UNKA can't be completed} — *end example*]
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5192)
[*Note [4](#note-4)*:
The rules for declarations and expressions describe in which
contexts incomplete types are prohibited[.](#7.sentence-1)
— *end note*]
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5198)
An [*object type*](#def:object_type "6.9.1General[basic.types.general]") is a (possibly cv-qualified) type that is not
a function type, not a reference type, and not cv void[.](#8.sentence-1)
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5203)
Arithmetic types ([[basic.fundamental]](basic.fundamental "6.9.2Fundamental types")), enumeration types,
pointer types, pointer-to-member types ([[basic.compound]](basic.compound "6.9.4Compound types")),std::meta::info, std::nullptr_t,
and[cv-qualified](basic.type.qualifier "6.9.5CV-qualifiers[basic.type.qualifier]") versions of these
types are collectively called[*scalar types*](#def:type,scalar "6.9.1General[basic.types.general]")[.](#9.sentence-1)
Scalar types, trivially copyable class types ([[class.prop]](class.prop "11.2Properties of classes")),
arrays of such types, and cv-qualified versions of these
types are collectively called [*trivially copyable types*](#def:type,trivially_copyable "6.9.1General[basic.types.general]")[.](#9.sentence-2)
Scalar types, trivially relocatable class types ([[class.prop]](class.prop "11.2Properties of classes")),
arrays of such types, and cv-qualified versions of these
types are collectively called [*trivially relocatable types*](#def:type,trivially_relocatable "6.9.1General[basic.types.general]")[.](#9.sentence-3)
Cv-unqualified scalar types, replaceable class types ([[class.prop]](class.prop "11.2Properties of classes")), and
arrays of such types are collectively called[*replaceable types*](#def:type,replaceable "6.9.1General[basic.types.general]")[.](#9.sentence-4)
Scalar types, standard-layout class
types ([[class.prop]](class.prop "11.2Properties of classes")), arrays of such types, and
cv-qualified versions of these types
are collectively called [*standard-layout types*](#def:type,standard-layout "6.9.1General[basic.types.general]")[.](#9.sentence-5)
Scalar types, implicit-lifetime class types ([[class.prop]](class.prop "11.2Properties of classes")),
array types, and cv-qualified versions of these types
are collectively called [*implicit-lifetime types*](#def:type,implicit-lifetime "6.9.1General[basic.types.general]")[.](#9.sentence-6)
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5238)
A type is a [*literal type*](#def:type,literal "6.9.1General[basic.types.general]") if it is:
- [(10.1)](#10.1)
cv void; or
- [(10.2)](#10.2)
a scalar type; or
- [(10.3)](#10.3)
a reference type; or
- [(10.4)](#10.4)
an array of literal type; or
- [(10.5)](#10.5)
a possibly cv-qualified [class type](class "11Classes[class]") that
has all of the following properties:
* [(10.5.1)](#10.5.1)
it has a constexpr destructor ([[dcl.constexpr]](dcl.constexpr "9.2.6The constexpr and consteval specifiers")),
* [(10.5.2)](#10.5.2)
all of its non-variant non-static data members and base classes are of non-volatile literal types, and
* [(10.5.3)](#10.5.3)
it
+
[(10.5.3.1)](#10.5.3.1)
is a closure type ([[expr.prim.lambda.closure]](expr.prim.lambda.closure "7.5.6.2Closure types")),
+
[(10.5.3.2)](#10.5.3.2)
is an aggregate union type that has either
no variant members or
at least one variant member of non-volatile literal type,
+
[(10.5.3.3)](#10.5.3.3)
is a non-union aggregate type for which
each of its anonymous union members
satisfies the above requirements for an aggregate union type, or
+
[(10.5.3.4)](#10.5.3.4)
has at least one constexpr constructor or constructor template
(possibly inherited ([[namespace.udecl]](namespace.udecl "9.10The using declaration")) from a base class)
that is not a copy or move constructor[.](#10.sentence-1)
[*Note [5](#note-5)*:
A literal type is one for which
it might be possible to create an object
within a constant expression[.](#10.sentence-2)
It is not a guarantee that it is possible to create such an object,
nor is it a guarantee that any object of that type
will be usable in a constant expression[.](#10.sentence-3)
— *end note*]
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5275)
Two types *cv1* T1 and *cv2* T2 are[*layout-compatible types*](#def:type,layout-compatible "6.9.1General[basic.types.general]") if T1 and T2 are the same type,[layout-compatible enumerations](dcl.enum#def:layout-compatible,enumeration "9.8.1Enumeration declarations[dcl.enum]"), or[layout-compatible standard-layout class types](class.mem#def:layout-compatible,class "11.4Class members[class.mem]")[.](#11.sentence-1)
[12](#12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5283)
A type is [*consteval-only*](#def:consteval-only "6.9.1General[basic.types.general]") if it is eitherstd::meta::info or
a type compounded from a consteval-only type ([[basic.compound]](basic.compound "6.9.4Compound types"))[.](#12.sentence-1)
Every object of consteval-only type shall be
- [(12.1)](#12.1)
the object associated with a constexpr variable or a subobject thereof,
- [(12.2)](#12.2)
a template parameter object ([[temp.param]](temp.param "13.2Template parameters")) or a subobject thereof, or
- [(12.3)](#12.3)
an object whose lifetime begins and ends
during the evaluation of a core constant expression[.](#12.sentence-2)
[26)](#footnote-26)[26)](#footnoteref-26)
By using, for example, the library
functions ([[headers]](headers "16.4.2.3Headers")) std::memcpy or std::memmove[.](#footnote-26.sentence-1)
[27)](#footnote-27)[27)](#footnoteref-27)
By using, for example,
the library functions ([[headers]](headers "16.4.2.3Headers")) std::memcpy or std::memmove[.](#footnote-27.sentence-1)
[28)](#footnote-28)[28)](#footnoteref-28)
The intent is that the memory model of C++ is compatible
with that of the C programming language[.](#footnote-28.sentence-1)
[29)](#footnote-29)[29)](#footnoteref-29)
The size and layout of an instance of an incompletely-defined
object type is unknown[.](#footnote-29.sentence-1)