265 lines
11 KiB
Markdown
265 lines
11 KiB
Markdown
[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.4 Compound types [basic.compound]") of objects of a given type, [[dcl.array]](dcl.array "9.3.4.5 Arrays");
|
||
|
||
- [(1.2)](#1.2)
|
||
|
||
[*functions*](dcl.fct#def:type,function "9.3.4.6 Functions [dcl.fct]"), which have parameters of given types and returnvoid or a result of a given type, [[dcl.fct]](dcl.fct "9.3.4.6 Functions");
|
||
|
||
- [(1.3)](#1.3)
|
||
|
||
[*pointers*](#def:type,pointer "6.9.4 Compound 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.2 Pointers");
|
||
|
||
- [(1.4)](#1.4)
|
||
|
||
[*references*](#def:reference "6.9.4 Compound types [basic.compound]") to objects or functions of a given
|
||
type, [[dcl.ref]](dcl.ref "9.3.4.3 References")[.](#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.4 Compound types [basic.compound]") containing a sequence of class members ([[class]](class "11 Classes"), [[class.mem]](class.mem "11.4 Class members")),
|
||
and a set of restrictions
|
||
on the access to these entities ([[class.access]](class.access "11.8 Member access control"));
|
||
|
||
- [(1.6)](#1.6)
|
||
|
||
[*unions*](#def:union "6.9.4 Compound types [basic.compound]"), which are classes capable of containing objects of
|
||
different types at different times, [[class.union]](class.union "11.5 Unions");
|
||
|
||
- [(1.7)](#1.7)
|
||
|
||
[*enumerations*](#def:enum "6.9.4 Compound types [basic.compound]"),
|
||
which comprise a set of named constant values, [[dcl.enum]](dcl.enum "9.8.1 Enumeration declarations");
|
||
|
||
- [(1.8)](#1.8)
|
||
|
||
[*pointers to non-static class members*](#def:pointer_to_member "6.9.4 Compound 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.4 Pointers 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.4 Compound 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.4 Meaning 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.2 Common 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.4 Compound 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.4 Compound 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.1 General"))[.](#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.4 Compound types [basic.compound]") an object or function (the pointer is said to [*point*](#def:point "6.9.4 Compound 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.4 Compound types [basic.compound]") an object ([[expr.add]](expr.add "7.6.6 Additive operators")), or
|
||
|
||
- [(3.3)](#3.3)
|
||
|
||
the [*null pointer value*](#def:value,null_pointer "6.9.4 Compound types [basic.compound]") for that type, or
|
||
|
||
- [(3.4)](#3.4)
|
||
|
||
an [*invalid pointer value*](#def:value,invalid_pointer "6.9.4 Compound 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.4 Compound types [basic.compound]") of
|
||
the first byte in memory ([[intro.memory]](intro.memory "6.8.1 Memory 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.6 Additive 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.6 Additive operators"))
|
||
and comparison ([[expr.rel]](expr.rel "7.6.9 Relational operators"), [[expr.eq]](expr.eq "7.6.10 Equality 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.3 Alignment"))[.](#3.sentence-13)
|
||
|
||
[*Note [3](#note-3)*:
|
||
|
||
Pointers to [over-aligned types](basic.align#def:type,over-aligned "6.8.3 Alignment [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.4 Compound 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.2 Unary operators")) or
|
||
an invocation of a deallocation function ([[basic.stc.dynamic.deallocation]](basic.stc.dynamic.deallocation "6.8.6.5.3 Deallocation 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.4 Lifetime"), [[basic.lval]](basic.lval "7.2.1 Value category"), [[expr.add]](expr.add "7.6.6 Additive 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.4 Compound 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.5 Unions")), 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.4 Class 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.10 Reinterpret 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.4 Compound 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)
|