Skip to content

[basic.stc.dynamic] Rework presentation #4451

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
202 changes: 108 additions & 94 deletions source/basic.tex
Original file line number Diff line number Diff line change
Expand Up @@ -3809,72 +3809,13 @@
\indextext{\idxcode{new}}%
\grammarterm{new-expression}{s}\iref{expr.new}, and destroyed using
\indextext{\idxcode{delete}}%
\grammarterm{delete-expression}{s}\iref{expr.delete}. A \Cpp{} implementation
provides access to, and management of, dynamic storage via
the global \defnx{allocation functions}{allocation function}
\tcode{\keyword{operator} \keyword{new}} and
\tcode{\keyword{operator} \keyword{new}[]} and
the global \defnx{deallocation functions}{deallocation function}
\tcode{\keyword{operator} \keyword{delete}} and
\tcode{\keyword{operator} \keyword{delete}[]}.
\grammarterm{delete-expression}{s}\iref{expr.delete},
which invoke allocation and deallocation functions, respectively.
\begin{note}
The non-allocating forms described in \ref{new.delete.placement}
do not perform allocation or deallocation.
\end{note}

\pnum
The library provides default definitions for the global allocation and
deallocation functions. Some global allocation and deallocation
functions are replaceable\iref{new.delete}. A \Cpp{} program shall
provide at most one definition of a replaceable allocation or
deallocation function. Any such function definition replaces the default
version provided in the library\iref{replacement.functions}. The
following allocation and deallocation functions\iref{support.dynamic}
are implicitly declared in global scope in each translation unit of a
program.

\begin{codeblock}
[[nodiscard]] void* operator new(std::size_t);
[[nodiscard]] 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;

[[nodiscard]] void* operator new[](std::size_t);
[[nodiscard]] 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;
\end{codeblock}

These implicit declarations introduce only the function names
\tcode{\keyword{operator} \keyword{new}},
\tcode{\keyword{operator} \keyword{new}[]},
\tcode{\keyword{operator} \keyword{delete}}, and
\tcode{\keyword{operator} \keyword{delete}[]}.
\begin{note}
The implicit declarations do not introduce
the names \tcode{std},
\tcode{std::size_t},
\tcode{std::align_val_t},
or any other names that the library uses to
declare these names. Thus, a \grammarterm{new-expression},
\grammarterm{delete-expression}, or function call that refers to one of
these functions without importing or including the header \libheaderref{new} is
well-formed. However, referring to \tcode{std}
or \tcode{std::size_t}
or \tcode{std::align_val_t}
is ill-formed unless the name has been declared
by importing or including the appropriate header.
\end{note}
Allocation and/or
deallocation functions may also be declared and defined for any
class\iref{class.free}.

\pnum
If the behavior of an allocation or deallocation function
does not satisfy the semantic constraints
Expand All @@ -3888,17 +3829,31 @@

\pnum
\indextext{function!allocation}%
An allocation function that is not a class member function
shall belong to the global scope and not have a name with internal linkage.
The return type shall be \tcode{\keyword{void}*}. The first
parameter shall have type \tcode{std::size_t}\iref{support.types}. The
first parameter shall not have an associated default
argument\iref{dcl.fct.default}. The value of the first parameter
is interpreted as the requested size of the allocation. An allocation
function can be a function template. 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 function templates shall have two or more parameters.
A function or function template
named \tcode{\keyword{operator} \keyword{new}} or \tcode{\keyword{operator} \keyword{new}[]}
is termed an \defnadj{operator new}{function}.

\pnum
An operator new function $F$ shall satisfy the following rules:
\begin{itemize}
\item
If $F$ is not a class member\iref{class.free},
it shall belong to the global scope and not have a name with internal linkage.
\item
The return type shall be (non-dependent) \tcode{\keyword{void}*}.
\item
The first parameter shall have non-dependent type \tcode{std::size_t}\iref{support.types}.
The first parameter shall not have
an associated default argument\iref{dcl.fct.default}.
\item
A function template shall have two or more function parameters.
\end{itemize}
Such a function or a specialization of such a function template is termed
an \defnadj{allocation}{function}.
The value of the first parameter is interpreted as
the requested size of the allocation.
An allocation function that belongs to the global scope is termed
a \defnadj{global allocation}{function}.

\pnum
An allocation function attempts to allocate the requested amount of
Expand Down Expand Up @@ -3988,31 +3943,43 @@
\rSec4[basic.stc.dynamic.deallocation]{Deallocation functions}

\pnum
\indextext{function!deallocation}%
A deallocation function that is not a class member function
shall belong to the global scope and not have a name with internal linkage.

\pnum
A deallocation function
A function or function template
named \tcode{operator delete} or \tcode{operator delete[]}
is termed an \defnadj{operator delete}{function}.
An operator delete function
is a \defnadj{destroying}{operator delete}
if it has at least two parameters
and its second parameter
is of type \tcode{std::destroying_delete_t}.
A destroying operator delete
shall be a class member function named \tcode{\keyword{operator} \keyword{delete}}.
is of non-dependent type \tcode{std::destroying_delete_t}.

\pnum
An operator delete function $F$ shall satisfy the following rules:
\begin{itemize}
\item
If $F$ is not a class member\iref{class.free},
it shall belong to the global scope and not have a name with internal linkage.
\item
If $F$ is a destroying operator delete,
it shall be a class member named \tcode{\keyword{operator} \keyword{delete}}.
\item
The return type shall be (non-dependent) \keyword{void}.
\item
If $F$ is a destroying operator delete declared in class type \tcode{C},
the first function parameter shall have non-dependent type \tcode{C*};
otherwise, the first function parameter shall have non-dependent type \tcode{void*}.
\item
A function template shall have two or more function parameters.
\end{itemize}
\begin{note}
Array deletion cannot use a destroying operator delete.
\end{note}
Such a function or a specialization of such a function template is termed
a \defnadj{deallocation}{function}.
A deallocation function that belongs to the global scope is termed
a \defnadj{global deallocation}{function}.

\pnum
\indextext{\idxcode{delete}!overloading and}%
Each deallocation function shall return \keyword{void}.
If the function is a destroying operator delete
declared in class type \tcode{C},
the type of its first parameter shall be \tcode{C*};
otherwise, the type of its first
parameter shall be \tcode{\keyword{void}*}. A deallocation function may have more
than one parameter.
\indextext{deallocation function!usual}%
A \defn{usual deallocation function} is a deallocation function
whose parameters after the first are
Expand All @@ -4032,12 +3999,8 @@
optionally, a parameter of type \tcode{std::align_val_t}.
\end{itemize}
A destroying operator delete shall be a usual deallocation function.
A deallocation function may be an instance of a function
template. Neither the first parameter nor the return type shall depend
on a template parameter.
A deallocation
function template shall have two or more function parameters. A template
instance is never a usual deallocation function, regardless of its
A specialization of a template
is never a usual deallocation function, regardless of its
signature.

\pnum
Expand All @@ -4052,6 +4015,57 @@
deallocation function shall deallocate the storage referenced by the
pointer, ending the duration of the region of storage.

\rSec4[basic.stc.dynamic.global]{Global allocation and deallocation functions}

\pnum
The library provides default definitions for the global allocation and
deallocation functions. Some global allocation and deallocation
functions are replaceable\iref{new.delete}. A \Cpp{} program shall
provide at most one definition of a replaceable allocation or
deallocation function. Any such function definition replaces the default
version provided in the library\iref{replacement.functions}. The
following allocation and deallocation functions\iref{support.dynamic}
are implicitly declared in global scope in each translation unit of a
program.

\begin{codeblock}
[[nodiscard]] void* operator new(std::size_t);
[[nodiscard]] 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;

[[nodiscard]] void* operator new[](std::size_t);
[[nodiscard]] 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;
\end{codeblock}

These implicit declarations introduce only the function names
\tcode{operator} \tcode{new}, \tcode{operator} \tcode{new[]},
\tcode{op\-er\-a\-tor} \tcode{delete}, and \tcode{operator}
\tcode{delete[]}.
\begin{note}
The implicit declarations do not introduce
the names \tcode{std},
\tcode{std::size_t},
\tcode{std::align_val_t},
or any other names that the library uses to
declare these names. Thus, a \grammarterm{new-expression},
\grammarterm{delete-expression}, or function call that refers to one of
these functions without importing or including the header \libheaderref{new} is
well-formed. However, referring to \tcode{std}
or \tcode{std::size_t}
or \tcode{std::align_val_t}
is ill-formed unless the name has been declared
by importing or including the appropriate header.
\end{note}

\rSec3[basic.stc.inherit]{Duration of subobjects}

\pnum
Expand Down