Files
2025-10-25 03:02:53 +03:00

265 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[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)