Update libstdc++ documentation for Support and Diagnostics clauses
* doc/xml/manual/diagnostics.xml: Update list of headers that define exception classes. * doc/xml/manual/support.xml: Rewrite advice around NULL. Rewrite section about new/delete overloads. Improve section on verbose terminate handler. * doc/html/*: Regenerate. From-SVN: r271782
This commit is contained in:
parent
30f78ec756
commit
01b3b9e39f
|
@ -1,5 +1,12 @@
|
|||
2019-05-30 Jonathan Wakely <jwakely@redhat.com>
|
||||
|
||||
* doc/xml/manual/diagnostics.xml: Update list of headers that define
|
||||
exception classes.
|
||||
* doc/xml/manual/support.xml: Rewrite advice around NULL. Rewrite
|
||||
section about new/delete overloads. Improve section on verbose
|
||||
terminate handler.
|
||||
* doc/html/*: Regenerate.
|
||||
|
||||
* doc/xml/manual/status_cxx2020.xml: Add feature-test macro for
|
||||
P0811R3. Change status of P1353R0.
|
||||
* doc/html/*: Regenerate.
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
</a></span></dt><dd><dl><dt><span class="chapter"><a href="manual/support.html">4.
|
||||
Support
|
||||
|
||||
</a></span></dt><dd><dl><dt><span class="section"><a href="manual/support.html#std.support.types">Types</a></span></dt><dd><dl><dt><span class="section"><a href="manual/support.html#std.support.types.fundamental">Fundamental Types</a></span></dt><dt><span class="section"><a href="manual/support.html#std.support.types.numeric_limits">Numeric Properties</a></span></dt><dt><span class="section"><a href="manual/support.html#std.support.types.null">NULL</a></span></dt></dl></dd><dt><span class="section"><a href="manual/dynamic_memory.html">Dynamic Memory</a></span></dt><dt><span class="section"><a href="manual/termination.html">Termination</a></span></dt><dd><dl><dt><span class="section"><a href="manual/termination.html#support.termination.handlers">Termination Handlers</a></span></dt><dt><span class="section"><a href="manual/termination.html#support.termination.verbose">Verbose Terminate Handler</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="manual/diagnostics.html">5.
|
||||
</a></span></dt><dd><dl><dt><span class="section"><a href="manual/support.html#std.support.types">Types</a></span></dt><dd><dl><dt><span class="section"><a href="manual/support.html#std.support.types.fundamental">Fundamental Types</a></span></dt><dt><span class="section"><a href="manual/support.html#std.support.types.numeric_limits">Numeric Properties</a></span></dt><dt><span class="section"><a href="manual/support.html#std.support.types.null">NULL</a></span></dt></dl></dd><dt><span class="section"><a href="manual/dynamic_memory.html">Dynamic Memory</a></span></dt><dd><dl><dt><span class="section"><a href="manual/dynamic_memory.html#std.support.memory.notes">Additional Notes</a></span></dt></dl></dd><dt><span class="section"><a href="manual/termination.html">Termination</a></span></dt><dd><dl><dt><span class="section"><a href="manual/termination.html#support.termination.handlers">Termination Handlers</a></span></dt><dt><span class="section"><a href="manual/termination.html#support.termination.verbose">Verbose Terminate Handler</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="manual/diagnostics.html">5.
|
||||
Diagnostics
|
||||
|
||||
</a></span></dt><dd><dl><dt><span class="section"><a href="manual/diagnostics.html#std.diagnostics.exceptions">Exceptions</a></span></dt><dd><dl><dt><span class="section"><a href="manual/diagnostics.html#std.diagnostics.exceptions.api">API Reference</a></span></dt><dt><span class="section"><a href="manual/diagnostics.html#std.diagnostics.exceptions.data">Adding Data to <code class="classname">exception</code></a></span></dt></dl></dd><dt><span class="section"><a href="manual/errno.html">Use of errno by the library</a></span></dt><dt><span class="section"><a href="manual/concept_checking.html">Concept Checking</a></span></dt></dl></dd><dt><span class="chapter"><a href="manual/utilities.html">6.
|
||||
|
|
|
@ -8,20 +8,32 @@
|
|||
Diagnostics
|
||||
<a id="id-1.3.4.3.1.1.1" class="indexterm"></a>
|
||||
</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="section"><a href="diagnostics.html#std.diagnostics.exceptions">Exceptions</a></span></dt><dd><dl><dt><span class="section"><a href="diagnostics.html#std.diagnostics.exceptions.api">API Reference</a></span></dt><dt><span class="section"><a href="diagnostics.html#std.diagnostics.exceptions.data">Adding Data to <code class="classname">exception</code></a></span></dt></dl></dd><dt><span class="section"><a href="errno.html">Use of errno by the library</a></span></dt><dt><span class="section"><a href="concept_checking.html">Concept Checking</a></span></dt></dl></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="std.diagnostics.exceptions"></a>Exceptions</h2></div></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="std.diagnostics.exceptions.api"></a>API Reference</h3></div></div></div><p>
|
||||
All exception objects are defined in one of the standard header
|
||||
files: <code class="filename">exception</code>,
|
||||
<code class="filename">stdexcept</code>, <code class="filename">new</code>, and
|
||||
<code class="filename">typeinfo</code>.
|
||||
Most exception classes are defined in one of the standard headers
|
||||
<code class="filename"><exception></code>,
|
||||
<code class="filename"><stdexcept></code>,
|
||||
<code class="filename"><new></code>, and
|
||||
<code class="filename"><typeinfo></code>.
|
||||
The C++ 2011 revision of the standard added more exception types
|
||||
in the headers
|
||||
<code class="filename"><functional></code>,
|
||||
<code class="filename"><future></code>,
|
||||
<code class="filename"><regex></code>, and
|
||||
<code class="filename"><system_error></code>.
|
||||
The C++ 2017 revision of the standard added more exception types
|
||||
in the headers
|
||||
<code class="filename"><any></code>,
|
||||
<code class="filename"><filesystem></code>,
|
||||
<code class="filename"><optional></code>, and
|
||||
<code class="filename"><variant></code>.
|
||||
</p><p>
|
||||
The base exception object is <code class="classname">exception</code>,
|
||||
located in <code class="filename">exception</code>. This object has no
|
||||
<code class="classname">string</code> member.
|
||||
All exceptions thrown by the library have a base class of type
|
||||
<code class="classname">std::exception</code>,
|
||||
defined in <code class="filename"><exception></code>.
|
||||
This type has no <code class="classname">std::string</code> member.
|
||||
</p><p>
|
||||
Derived from this are several classes that may have a
|
||||
<code class="classname">string</code> member: a full hierarchy can be
|
||||
<code class="classname">std::string</code> member. A full hierarchy can be
|
||||
found in the source documentation.
|
||||
</p><p>
|
||||
Full API details.
|
||||
</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="std.diagnostics.exceptions.data"></a>Adding Data to <code class="classname">exception</code></h3></div></div></div><p>
|
||||
The standard exception classes carry with them a single string as
|
||||
data (usually describing what went wrong or where the 'throw' took
|
||||
|
|
|
@ -3,45 +3,120 @@
|
|||
Support
|
||||
|
||||
</th><td width="20%" align="right"> <a accesskey="n" href="termination.html">Next</a></td></tr></table><hr /></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="std.support.memory"></a>Dynamic Memory</h2></div></div></div><p>
|
||||
There are six flavors each of <code class="function">new</code> and
|
||||
<code class="function">delete</code>, so make certain that you're using the right
|
||||
ones. Here are quickie descriptions of <code class="function">new</code>:
|
||||
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
|
||||
single object form, throwing a
|
||||
<code class="classname">bad_alloc</code> on errors; this is what most
|
||||
people are used to using
|
||||
</p></li><li class="listitem"><p>
|
||||
Single object "nothrow" form, returning NULL on errors
|
||||
</p></li><li class="listitem"><p>
|
||||
Array <code class="function">new</code>, throwing
|
||||
<code class="classname">bad_alloc</code> on errors
|
||||
</p></li><li class="listitem"><p>
|
||||
Array nothrow <code class="function">new</code>, returning
|
||||
<code class="constant">NULL</code> on errors
|
||||
</p></li><li class="listitem"><p>
|
||||
Placement <code class="function">new</code>, which does nothing (like
|
||||
it's supposed to)
|
||||
</p></li><li class="listitem"><p>
|
||||
Placement array <code class="function">new</code>, which also does
|
||||
nothing
|
||||
</p></li></ul></div><p>
|
||||
They are distinguished by the parameters that you pass to them, like
|
||||
any other overloaded function. The six flavors of <code class="function">delete</code>
|
||||
In C++98 there are six flavors each of <code class="function">operator new</code>
|
||||
and <code class="function">operator delete</code>, so make certain that you're
|
||||
using the right ones.
|
||||
Here are quickie descriptions of <code class="function">operator new</code>:
|
||||
</p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="code">void* operator new(std::size_t);</code></span></dt><dd>
|
||||
Single object form.
|
||||
Throws <code class="classname">std::bad_alloc</code> on error.
|
||||
This is what most people are used to using.
|
||||
</dd><dt><span class="term"><code class="code">void* operator new(std::size_t, std::nothrow_t) noexcept;</code></span></dt><dd>
|
||||
Single object <span class="quote">“<span class="quote">nothrow</span>”</span> form.
|
||||
Calls <code class="code">operator new(std::size_t)</code> but if that throws,
|
||||
returns a null pointer instead.
|
||||
</dd><dt><span class="term"><code class="code">void* operator new[](std::size_t);</code></span></dt><dd>
|
||||
Array <code class="function">new</code>.
|
||||
Calls <code class="code">operator new(std::size_t)</code> and so
|
||||
throws <code class="classname">std::bad_alloc</code> on error.
|
||||
</dd><dt><span class="term"><code class="code">void* operator new[](std::size_t, std::nothrow_t) noexcept;</code></span></dt><dd>
|
||||
Array <span class="quote">“<span class="quote">nothrow</span>”</span><code class="function">new</code>.
|
||||
Calls <code class="code">operator new[](std::size_t)</code> but if that throws,
|
||||
returns a null pointer instead.
|
||||
</dd><dt><span class="term"><code class="code">void* operator new(std::size_t, void*) noexcept;</code></span></dt><dd>
|
||||
Non-allocating, <span class="quote">“<span class="quote">placement</span>”</span> single-object <code class="function">new</code>,
|
||||
which does nothing except return its argument.
|
||||
This function cannot be replaced.
|
||||
</dd><dt><span class="term"><code class="code">void* operator new[](std::size_t, void*) noexcept;</code></span></dt><dd>
|
||||
Non-allocating, <span class="quote">“<span class="quote">placement</span>”</span> array <code class="function">new</code>,
|
||||
which also does nothing except return its argument.
|
||||
This function cannot be replaced.
|
||||
</dd></dl></div><p>
|
||||
They are distinguished by the arguments that you pass to them, like
|
||||
any other overloaded function. The six flavors of
|
||||
<code class="function">operator delete</code>
|
||||
are distinguished the same way, but none of them are allowed to throw
|
||||
an exception under any circumstances anyhow. (They match up for
|
||||
completeness' sake.)
|
||||
an exception under any circumstances anyhow. (The overloads match up
|
||||
with the ones above, for completeness' sake.)
|
||||
</p><p>
|
||||
Remember that it is perfectly okay to call <code class="function">delete</code> on a
|
||||
NULL pointer! Nothing happens, by definition. That is not the
|
||||
same thing as deleting a pointer twice.
|
||||
The C++ 2014 revision of the standard added two additional overloads of
|
||||
<code class="function">operator delete</code> for <span class="quote">“<span class="quote">sized deallocation</span>”</span>,
|
||||
allowing the compiler to provide the size of the storage being freed.
|
||||
</p><p>
|
||||
By default, if one of the <span class="quote">“<span class="quote">throwing <code class="function">new</code>s</span>”</span> can't
|
||||
allocate the memory requested, it tosses an instance of a
|
||||
<code class="classname">bad_alloc</code> exception (or, technically, some class derived
|
||||
from it). You can change this by writing your own function (called a
|
||||
new-handler) and then registering it with <code class="function">set_new_handler()</code>:
|
||||
The C++ 2017 standard added even more overloads of both
|
||||
<code class="function">operator new</code> and <code class="function">operator delete</code>
|
||||
for allocating and deallocating storage for overaligned types.
|
||||
These overloads correspond to each of the allocating forms of
|
||||
<code class="function">operator new</code> and <code class="function">operator delete</code>
|
||||
but with an additional parameter of type <span class="type">std::align_val_t</span>.
|
||||
These new overloads are not interchangeable with the versions without
|
||||
an aligment parameter, so if memory was allocated by an overload of
|
||||
<code class="function">operator new</code> taking an alignment parameter,
|
||||
then it must be decallocated by the corresponding overload of
|
||||
<code class="function">operator delete</code> that takes an alignment parameter.
|
||||
</p><p>
|
||||
Apart from the non-allocating forms, the default versions of the array
|
||||
and nothrow <code class="function">operator new</code> functions will all result
|
||||
in a call to either <code class="function">operator new(std::size_t)</code> or
|
||||
<code class="function">operator new(std::size_t, std::align_val_t)</code>,
|
||||
and similarly the default versions of the array and nothrow
|
||||
<code class="function">operator delete</code> functions will result in a call to
|
||||
either <code class="function">operator delete(void*)</code> or
|
||||
<code class="function">operator delete(void*, std::align_val_t)</code>
|
||||
(or the sized versions of those).
|
||||
</p><p>
|
||||
Apart from the non-allocating forms, any of these functions can be
|
||||
replaced by defining a function with the same signature in your program.
|
||||
Replacement versions must preserve certain guarantees, such as memory
|
||||
obtained from a nothrow <code class="function">operator new</code> being free-able
|
||||
by the normal (non-nothrow) <code class="function">operator delete</code>,
|
||||
and the sized and unsized forms of <code class="function">operator delete</code>
|
||||
being interchangeable (because it's unspecified whether
|
||||
the compiler calls the sized delete instead of the normal one).
|
||||
The simplest way to meet the guarantees is to only replace the ordinary
|
||||
<code class="function">operator new(size_t)</code> and
|
||||
<code class="function">operator delete(void*)</code> and
|
||||
<code class="function">operator delete(void*, std::size_t)</code>
|
||||
functions, and the replaced versions will be used by all of
|
||||
<code class="function">operator new(size_t, nothrow_t)</code>,
|
||||
<code class="function">operator new[](size_t)</code> and
|
||||
<code class="function">operator new[](size_t, nothrow_t)</code>
|
||||
and the corresponding <code class="function">operator delete</code> functions.
|
||||
To support types with extended alignment you may also need to replace
|
||||
<code class="function">operator new(size_t, align_val_t)</code> and
|
||||
<code class="function">operator delete(void*, align_val_t)</code>
|
||||
<code class="function">operator delete(void*, size_t, align_val_t)</code>
|
||||
(which will then be used by the nothrow and array forms for
|
||||
extended alignments).
|
||||
If you do need to replace other forms (e.g. to define the nothrow
|
||||
<code class="function">operator new</code> to allocate memory directly, so it
|
||||
works with exceptions disabled) then make sure the memory it allocates
|
||||
can still be freed by the non-nothrow forms of
|
||||
<code class="function">operator delete</code>.
|
||||
</p><p>
|
||||
If the default versions of <code class="function">operator new(std::size_t)</code>
|
||||
and <code class="function">operator new(size_t, std::align_val_t)</code>
|
||||
can't allocate the memory requested, they usually throw an exception
|
||||
object of type <code class="classname">std::bad_alloc</code> (or some class
|
||||
derived from that). However, the program can influence that behavior
|
||||
by registering a <span class="quote">“<span class="quote">new-handler</span>”</span>, because what
|
||||
<code class="function">operator new</code> actually does is something like:
|
||||
</p><pre class="programlisting">
|
||||
typedef void (*PFV)(void);
|
||||
while (true)
|
||||
{
|
||||
if (void* p = /* try to allocate memory */)
|
||||
return p;
|
||||
else if (std::new_handler h = std::get_new_handler ())
|
||||
h ();
|
||||
else
|
||||
throw bad_alloc{};
|
||||
}
|
||||
</pre><p>
|
||||
This means you can influence what happens on allocation failure by
|
||||
writing your own new-handler and then registering it with
|
||||
<code class="function">std::set_new_handler</code>:
|
||||
</p><pre class="programlisting">
|
||||
typedef void (*PFV)();
|
||||
|
||||
static char* safety;
|
||||
static PFV old_handler;
|
||||
|
@ -49,6 +124,7 @@
|
|||
void my_new_handler ()
|
||||
{
|
||||
delete[] safety;
|
||||
safety = nullptr;
|
||||
popup_window ("Dude, you are running low on heap memory. You"
|
||||
" should, like, close some windows, or something."
|
||||
" The next time you run out, we're gonna burn!");
|
||||
|
@ -62,10 +138,15 @@
|
|||
old_handler = set_new_handler (&my_new_handler);
|
||||
...
|
||||
}
|
||||
</pre><p>
|
||||
<code class="classname">bad_alloc</code> is derived from the base <code class="classname">exception</code>
|
||||
class defined in Sect1 19.
|
||||
</p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="support.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="support.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="termination.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 4.
|
||||
</pre><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="std.support.memory.notes"></a>Additional Notes</h3></div></div></div><p>
|
||||
Remember that it is perfectly okay to <code class="function">delete</code> a
|
||||
null pointer! Nothing happens, by definition. That is not the
|
||||
same thing as deleting a pointer twice.
|
||||
</p><p>
|
||||
<code class="classname">std::bad_alloc</code> is derived from the base
|
||||
<code class="classname">std::exception</code> class,
|
||||
see <a class="xref" href="diagnostics.html#std.diagnostics.exceptions" title="Exceptions">Exceptions</a>.
|
||||
</p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="support.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="support.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="termination.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 4.
|
||||
Support
|
||||
|
||||
</td><td width="20%" align="center"><a accesskey="h" href="../index.html">Home</a></td><td width="40%" align="right" valign="top"> Termination</td></tr></table></div></body></html>
|
|
@ -9,7 +9,7 @@
|
|||
</a></span></dt><dd><dl><dt><span class="chapter"><a href="support.html">4.
|
||||
Support
|
||||
|
||||
</a></span></dt><dd><dl><dt><span class="section"><a href="support.html#std.support.types">Types</a></span></dt><dd><dl><dt><span class="section"><a href="support.html#std.support.types.fundamental">Fundamental Types</a></span></dt><dt><span class="section"><a href="support.html#std.support.types.numeric_limits">Numeric Properties</a></span></dt><dt><span class="section"><a href="support.html#std.support.types.null">NULL</a></span></dt></dl></dd><dt><span class="section"><a href="dynamic_memory.html">Dynamic Memory</a></span></dt><dt><span class="section"><a href="termination.html">Termination</a></span></dt><dd><dl><dt><span class="section"><a href="termination.html#support.termination.handlers">Termination Handlers</a></span></dt><dt><span class="section"><a href="termination.html#support.termination.verbose">Verbose Terminate Handler</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="diagnostics.html">5.
|
||||
</a></span></dt><dd><dl><dt><span class="section"><a href="support.html#std.support.types">Types</a></span></dt><dd><dl><dt><span class="section"><a href="support.html#std.support.types.fundamental">Fundamental Types</a></span></dt><dt><span class="section"><a href="support.html#std.support.types.numeric_limits">Numeric Properties</a></span></dt><dt><span class="section"><a href="support.html#std.support.types.null">NULL</a></span></dt></dl></dd><dt><span class="section"><a href="dynamic_memory.html">Dynamic Memory</a></span></dt><dd><dl><dt><span class="section"><a href="dynamic_memory.html#std.support.memory.notes">Additional Notes</a></span></dt></dl></dd><dt><span class="section"><a href="termination.html">Termination</a></span></dt><dd><dl><dt><span class="section"><a href="termination.html#support.termination.handlers">Termination Handlers</a></span></dt><dt><span class="section"><a href="termination.html#support.termination.verbose">Verbose Terminate Handler</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="diagnostics.html">5.
|
||||
Diagnostics
|
||||
|
||||
</a></span></dt><dd><dl><dt><span class="section"><a href="diagnostics.html#std.diagnostics.exceptions">Exceptions</a></span></dt><dd><dl><dt><span class="section"><a href="diagnostics.html#std.diagnostics.exceptions.api">API Reference</a></span></dt><dt><span class="section"><a href="diagnostics.html#std.diagnostics.exceptions.data">Adding Data to <code class="classname">exception</code></a></span></dt></dl></dd><dt><span class="section"><a href="errno.html">Use of errno by the library</a></span></dt><dt><span class="section"><a href="concept_checking.html">Concept Checking</a></span></dt></dl></dd><dt><span class="chapter"><a href="utilities.html">6.
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
</h1></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="chapter"><a href="support.html">4.
|
||||
Support
|
||||
|
||||
</a></span></dt><dd><dl><dt><span class="section"><a href="support.html#std.support.types">Types</a></span></dt><dd><dl><dt><span class="section"><a href="support.html#std.support.types.fundamental">Fundamental Types</a></span></dt><dt><span class="section"><a href="support.html#std.support.types.numeric_limits">Numeric Properties</a></span></dt><dt><span class="section"><a href="support.html#std.support.types.null">NULL</a></span></dt></dl></dd><dt><span class="section"><a href="dynamic_memory.html">Dynamic Memory</a></span></dt><dt><span class="section"><a href="termination.html">Termination</a></span></dt><dd><dl><dt><span class="section"><a href="termination.html#support.termination.handlers">Termination Handlers</a></span></dt><dt><span class="section"><a href="termination.html#support.termination.verbose">Verbose Terminate Handler</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="diagnostics.html">5.
|
||||
</a></span></dt><dd><dl><dt><span class="section"><a href="support.html#std.support.types">Types</a></span></dt><dd><dl><dt><span class="section"><a href="support.html#std.support.types.fundamental">Fundamental Types</a></span></dt><dt><span class="section"><a href="support.html#std.support.types.numeric_limits">Numeric Properties</a></span></dt><dt><span class="section"><a href="support.html#std.support.types.null">NULL</a></span></dt></dl></dd><dt><span class="section"><a href="dynamic_memory.html">Dynamic Memory</a></span></dt><dd><dl><dt><span class="section"><a href="dynamic_memory.html#std.support.memory.notes">Additional Notes</a></span></dt></dl></dd><dt><span class="section"><a href="termination.html">Termination</a></span></dt><dd><dl><dt><span class="section"><a href="termination.html#support.termination.handlers">Termination Handlers</a></span></dt><dt><span class="section"><a href="termination.html#support.termination.verbose">Verbose Terminate Handler</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="diagnostics.html">5.
|
||||
Diagnostics
|
||||
|
||||
</a></span></dt><dd><dl><dt><span class="section"><a href="diagnostics.html#std.diagnostics.exceptions">Exceptions</a></span></dt><dd><dl><dt><span class="section"><a href="diagnostics.html#std.diagnostics.exceptions.api">API Reference</a></span></dt><dt><span class="section"><a href="diagnostics.html#std.diagnostics.exceptions.data">Adding Data to <code class="classname">exception</code></a></span></dt></dl></dd><dt><span class="section"><a href="errno.html">Use of errno by the library</a></span></dt><dt><span class="section"><a href="concept_checking.html">Concept Checking</a></span></dt></dl></dd><dt><span class="chapter"><a href="utilities.html">6.
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
</th><td width="20%" align="right"> <a accesskey="n" href="dynamic_memory.html">Next</a></td></tr></table><hr /></div><div class="chapter"><div class="titlepage"><div><div><h2 class="title"><a id="std.support"></a>Chapter 4.
|
||||
Support
|
||||
<a id="id-1.3.4.2.1.1.1" class="indexterm"></a>
|
||||
</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="section"><a href="support.html#std.support.types">Types</a></span></dt><dd><dl><dt><span class="section"><a href="support.html#std.support.types.fundamental">Fundamental Types</a></span></dt><dt><span class="section"><a href="support.html#std.support.types.numeric_limits">Numeric Properties</a></span></dt><dt><span class="section"><a href="support.html#std.support.types.null">NULL</a></span></dt></dl></dd><dt><span class="section"><a href="dynamic_memory.html">Dynamic Memory</a></span></dt><dt><span class="section"><a href="termination.html">Termination</a></span></dt><dd><dl><dt><span class="section"><a href="termination.html#support.termination.handlers">Termination Handlers</a></span></dt><dt><span class="section"><a href="termination.html#support.termination.verbose">Verbose Terminate Handler</a></span></dt></dl></dd></dl></div><p>
|
||||
</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="section"><a href="support.html#std.support.types">Types</a></span></dt><dd><dl><dt><span class="section"><a href="support.html#std.support.types.fundamental">Fundamental Types</a></span></dt><dt><span class="section"><a href="support.html#std.support.types.numeric_limits">Numeric Properties</a></span></dt><dt><span class="section"><a href="support.html#std.support.types.null">NULL</a></span></dt></dl></dd><dt><span class="section"><a href="dynamic_memory.html">Dynamic Memory</a></span></dt><dd><dl><dt><span class="section"><a href="dynamic_memory.html#std.support.memory.notes">Additional Notes</a></span></dt></dl></dd><dt><span class="section"><a href="termination.html">Termination</a></span></dt><dd><dl><dt><span class="section"><a href="termination.html#support.termination.handlers">Termination Handlers</a></span></dt><dt><span class="section"><a href="termination.html#support.termination.verbose">Verbose Terminate Handler</a></span></dt></dl></dd></dl></div><p>
|
||||
This part deals with the functions called and objects created
|
||||
automatically during the course of a program's existence.
|
||||
</p><p>
|
||||
|
@ -53,7 +53,7 @@
|
|||
Specializing parts of the library on these types is prohibited:
|
||||
instead, use a POD.
|
||||
</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="std.support.types.numeric_limits"></a>Numeric Properties</h3></div></div></div><p>
|
||||
The header <code class="filename">limits</code> defines
|
||||
The header <code class="filename"><limits></code> defines
|
||||
traits classes to give access to various implementation
|
||||
defined-aspects of the fundamental types. The traits classes --
|
||||
fourteen in total -- are all specializations of the class template
|
||||
|
@ -102,28 +102,36 @@
|
|||
The only change that might affect people is the type of
|
||||
<code class="constant">NULL</code>: while it is required to be a macro,
|
||||
the definition of that macro is <span class="emphasis"><em>not</em></span> allowed
|
||||
to be <code class="constant">(void*)0</code>, which is often used in C.
|
||||
to be an expression with pointer type such as
|
||||
<code class="constant">(void*)0</code>, which is often used in C.
|
||||
</p><p>
|
||||
For <span class="command"><strong>g++</strong></span>, <code class="constant">NULL</code> is
|
||||
<code class="code">#define</code>'d to be
|
||||
<code class="constant">__null</code>, a magic keyword extension of
|
||||
<span class="command"><strong>g++</strong></span>.
|
||||
<span class="command"><strong>g++</strong></span> that is slightly safer than a plain integer.
|
||||
</p><p>
|
||||
The biggest problem of #defining <code class="constant">NULL</code> to be
|
||||
something like <span class="quote">“<span class="quote">0L</span>”</span> is that the compiler will view
|
||||
that as a long integer before it views it as a pointer, so
|
||||
overloading won't do what you expect. (This is why
|
||||
<span class="command"><strong>g++</strong></span> has a magic extension, so that
|
||||
<code class="constant">NULL</code> is always a pointer.)
|
||||
</p><p>In his book <a class="link" href="http://www.aristeia.com/books.html" target="_top"><span class="emphasis"><em>Effective
|
||||
C++</em></span></a>, Scott Meyers points out that the best way
|
||||
to solve this problem is to not overload on pointer-vs-integer
|
||||
types to begin with. He also offers a way to make your own magic
|
||||
<code class="constant">NULL</code> that will match pointers before it
|
||||
matches integers.
|
||||
</p><p>See the
|
||||
<a class="link" href="http://www.aristeia.com/books.html" target="_top"><span class="emphasis"><em>Effective
|
||||
C++ CD</em></span></a> example.
|
||||
overloading won't do what you expect. It might not even have the
|
||||
same size as a pointer, so passing <code class="constant">NULL</code> to a
|
||||
varargs function where a pointer is expected might not even work
|
||||
correctly if <code class="code">sizeof(NULL) < sizeof(void*)</code>.
|
||||
The G++ <code class="constant">__null</code> extension is defined so that
|
||||
<code class="code">sizeof(__null) == sizeof(void*)</code> to avoid this problem.
|
||||
</p><p>
|
||||
Scott Meyers explains this in more detail in his book
|
||||
<a class="link" href="https://www.aristeia.com/books.html" target="_top"><span class="emphasis"><em>Effective
|
||||
Modern C++</em></span></a> and as a guideline to solve this problem
|
||||
recommends to not overload on pointer-vs-integer types to begin with.
|
||||
</p><p>
|
||||
The C++ 2011 standard added the <code class="constant">nullptr</code> keyword,
|
||||
which is a null pointer constant of a special type,
|
||||
<code class="classname">std::nullptr_t</code>. Values of this type can be
|
||||
implicitly converted to <span class="emphasis"><em>any</em></span> pointer type,
|
||||
and cannot convert to integer types or be deduced as an integer type.
|
||||
Unless you need to be compatible with C++98/C++03 or C you should prefer
|
||||
to use <code class="constant">nullptr</code> instead of <code class="constant">NULL</code>.
|
||||
</p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="std_contents.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="std_contents.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="dynamic_memory.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Part II.
|
||||
Standard Contents
|
||||
</td><td width="20%" align="center"><a accesskey="h" href="../index.html">Home</a></td><td width="40%" align="right" valign="top"> Dynamic Memory</td></tr></table></div></body></html>
|
|
@ -3,7 +3,9 @@
|
|||
Support
|
||||
|
||||
</th><td width="20%" align="right"> <a accesskey="n" href="diagnostics.html">Next</a></td></tr></table><hr /></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="std.support.termination"></a>Termination</h2></div></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="support.termination.handlers"></a>Termination Handlers</h3></div></div></div><p>
|
||||
Not many changes here to <code class="filename">cstdlib</code>. You should note that the
|
||||
Not many changes here to
|
||||
<code class="filename"><cstdlib></code>.
|
||||
You should note that the
|
||||
<code class="function">abort()</code> function does not call the
|
||||
destructors of automatic nor static objects, so if you're
|
||||
depending on those to do cleanup, it isn't going to happen.
|
||||
|
@ -24,8 +26,8 @@
|
|||
The previous two actions are <span class="quote">“<span class="quote">interleaved,</span>”</span> that is,
|
||||
given this pseudocode:
|
||||
</p><pre class="programlisting">
|
||||
extern "C or C++" void f1 (void);
|
||||
extern "C or C++" void f2 (void);
|
||||
extern "C or C++" void f1 ();
|
||||
extern "C or C++" void f2 ();
|
||||
|
||||
static Thing obj1;
|
||||
atexit(f1);
|
||||
|
@ -43,11 +45,20 @@
|
|||
Note also that <code class="function">atexit()</code> is only required to store 32
|
||||
functions, and the compiler/library might already be using some of
|
||||
those slots. If you think you may run out, we recommend using
|
||||
the <code class="function">xatexit</code>/<code class="function">xexit</code> combination from <code class="literal">libiberty</code>, which has no such limit.
|
||||
the <code class="function">xatexit</code>/<code class="function">xexit</code> combination
|
||||
from <code class="literal">libiberty</code>, which has no such limit.
|
||||
</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="support.termination.verbose"></a>Verbose Terminate Handler</h3></div></div></div><p>
|
||||
If you are having difficulty with uncaught exceptions and want a
|
||||
little bit of help debugging the causes of the core dumps, you can
|
||||
make use of a GNU extension, the verbose terminate handler.
|
||||
</p><p>
|
||||
The verbose terminate handler is only available for hosted environments
|
||||
(see <a class="xref" href="configure.html" title="Configure">Configuring</a>) and will be used
|
||||
by default unless the library is built with
|
||||
<code class="option">--disable-libstdcxx-verbose</code>
|
||||
or with exceptions disabled.
|
||||
If you need to enable it explicitly you can do so by calling the
|
||||
<code class="function">std::set_terminate</code> function.
|
||||
</p><pre class="programlisting">
|
||||
#include <exception>
|
||||
|
||||
|
@ -61,12 +72,13 @@ int main()
|
|||
</pre><p>
|
||||
The <code class="function">__verbose_terminate_handler</code> function
|
||||
obtains the name of the current exception, attempts to demangle
|
||||
it, and prints it to stderr. If the exception is derived from
|
||||
<code class="classname">exception</code> then the output from
|
||||
it, and prints it to <code class="literal">stderr</code>.
|
||||
If the exception is derived from
|
||||
<code class="classname">std::exception</code> then the output from
|
||||
<code class="function">what()</code> will be included.
|
||||
</p><p>
|
||||
Any replacement termination function is required to kill the
|
||||
program without returning; this one calls abort.
|
||||
program without returning; this one calls <code class="function">std::abort</code>.
|
||||
</p><p>
|
||||
For example:
|
||||
</p><pre class="programlisting">
|
||||
|
@ -99,13 +111,14 @@ int main(int argc)
|
|||
Aborted
|
||||
</code>
|
||||
</pre><p>
|
||||
The 'Aborted' line comes from the call to
|
||||
<code class="function">abort()</code>, of course.
|
||||
The 'Aborted' line is printed by the shell after the process exits
|
||||
by calling <code class="function">abort()</code>.
|
||||
</p><p>
|
||||
This is the default termination handler; nothing need be done to
|
||||
As this is the default termination handler, nothing need be done to
|
||||
use it. To go back to the previous <span class="quote">“<span class="quote">silent death</span>”</span>
|
||||
method, simply include <code class="filename">exception</code> and
|
||||
<code class="filename">cstdlib</code>, and call
|
||||
method, simply include
|
||||
<code class="filename"><exception></code> and
|
||||
<code class="filename"><cstdlib></code>, and call
|
||||
</p><pre class="programlisting">
|
||||
std::set_terminate(std::abort);
|
||||
</pre><p>
|
||||
|
@ -113,8 +126,8 @@ int main(int argc)
|
|||
<code class="function">abort</code> as the terminate handler.
|
||||
</p><p>
|
||||
Note: the verbose terminate handler will attempt to write to
|
||||
stderr. If your application closes stderr or redirects it to an
|
||||
inappropriate location,
|
||||
<code class="literal">stderr</code>. If your application closes
|
||||
<code class="literal">stderr</code> or redirects it to an inappropriate location,
|
||||
<code class="function">__verbose_terminate_handler</code> will behave in
|
||||
an unspecified manner.
|
||||
</p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="dynamic_memory.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="support.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="diagnostics.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Dynamic Memory </td><td width="20%" align="center"><a accesskey="h" href="../index.html">Home</a></td><td width="40%" align="right" valign="top"> Chapter 5.
|
||||
|
|
|
@ -21,28 +21,38 @@
|
|||
<section xml:id="std.diagnostics.exceptions.api"><info><title>API Reference</title></info>
|
||||
|
||||
<para>
|
||||
All exception objects are defined in one of the standard header
|
||||
files: <filename>exception</filename>,
|
||||
<filename>stdexcept</filename>, <filename>new</filename>, and
|
||||
<filename>typeinfo</filename>.
|
||||
Most exception classes are defined in one of the standard headers
|
||||
<filename class="headerfile"><exception></filename>,
|
||||
<filename class="headerfile"><stdexcept></filename>,
|
||||
<filename class="headerfile"><new></filename>, and
|
||||
<filename class="headerfile"><typeinfo></filename>.
|
||||
The C++ 2011 revision of the standard added more exception types
|
||||
in the headers
|
||||
<filename class="headerfile"><functional></filename>,
|
||||
<filename class="headerfile"><future></filename>,
|
||||
<filename class="headerfile"><regex></filename>, and
|
||||
<filename class="headerfile"><system_error></filename>.
|
||||
The C++ 2017 revision of the standard added more exception types
|
||||
in the headers
|
||||
<filename class="headerfile"><any></filename>,
|
||||
<filename class="headerfile"><filesystem></filename>,
|
||||
<filename class="headerfile"><optional></filename>, and
|
||||
<filename class="headerfile"><variant></filename>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The base exception object is <classname>exception</classname>,
|
||||
located in <filename>exception</filename>. This object has no
|
||||
<classname>string</classname> member.
|
||||
All exceptions thrown by the library have a base class of type
|
||||
<classname>std::exception</classname>,
|
||||
defined in <filename class="headerfile"><exception></filename>.
|
||||
This type has no <classname>std::string</classname> member.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Derived from this are several classes that may have a
|
||||
<classname>string</classname> member: a full hierarchy can be
|
||||
<classname>std::string</classname> member. A full hierarchy can be
|
||||
found in the source documentation.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Full API details.
|
||||
</para>
|
||||
|
||||
<!-- Doxygen XML: api/group__exceptions.xml -->
|
||||
|
||||
</section>
|
||||
|
|
|
@ -26,9 +26,9 @@
|
|||
|
||||
<section xml:id="std.support.types" xreflabel="Types"><info><title>Types</title></info>
|
||||
<?dbhtml filename="fundamental_types.html"?>
|
||||
|
||||
|
||||
<section xml:id="std.support.types.fundamental" xreflabel="Fundamental Types"><info><title>Fundamental Types</title></info>
|
||||
|
||||
|
||||
<para>
|
||||
C++ has the following builtin types:
|
||||
</para>
|
||||
|
@ -90,11 +90,9 @@
|
|||
|
||||
</section>
|
||||
<section xml:id="std.support.types.numeric_limits" xreflabel="Numeric Properties"><info><title>Numeric Properties</title></info>
|
||||
|
||||
|
||||
|
||||
<para>
|
||||
The header <filename class="headerfile">limits</filename> defines
|
||||
The header <filename class="headerfile"><limits></filename> defines
|
||||
traits classes to give access to various implementation
|
||||
defined-aspects of the fundamental types. The traits classes --
|
||||
fourteen in total -- are all specializations of the class template
|
||||
|
@ -145,42 +143,50 @@
|
|||
</section>
|
||||
|
||||
<section xml:id="std.support.types.null" xreflabel="NULL"><info><title>NULL</title></info>
|
||||
|
||||
|
||||
<para>
|
||||
The only change that might affect people is the type of
|
||||
<constant>NULL</constant>: while it is required to be a macro,
|
||||
the definition of that macro is <emphasis>not</emphasis> allowed
|
||||
to be <constant>(void*)0</constant>, which is often used in C.
|
||||
to be an expression with pointer type such as
|
||||
<constant>(void*)0</constant>, which is often used in C.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For <command>g++</command>, <constant>NULL</constant> is
|
||||
<code>#define</code>'d to be
|
||||
<constant>__null</constant>, a magic keyword extension of
|
||||
<command>g++</command>.
|
||||
<command>g++</command> that is slightly safer than a plain integer.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The biggest problem of #defining <constant>NULL</constant> to be
|
||||
something like <quote>0L</quote> is that the compiler will view
|
||||
that as a long integer before it views it as a pointer, so
|
||||
overloading won't do what you expect. (This is why
|
||||
<command>g++</command> has a magic extension, so that
|
||||
<constant>NULL</constant> is always a pointer.)
|
||||
overloading won't do what you expect. It might not even have the
|
||||
same size as a pointer, so passing <constant>NULL</constant> to a
|
||||
varargs function where a pointer is expected might not even work
|
||||
correctly if <code>sizeof(NULL) < sizeof(void*)</code>.
|
||||
The G++ <constant>__null</constant> extension is defined so that
|
||||
<code>sizeof(__null) == sizeof(void*)</code> to avoid this problem.
|
||||
</para>
|
||||
|
||||
<para>In his book <link xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xlink:href="http://www.aristeia.com/books.html"><emphasis>Effective
|
||||
C++</emphasis></link>, Scott Meyers points out that the best way
|
||||
to solve this problem is to not overload on pointer-vs-integer
|
||||
types to begin with. He also offers a way to make your own magic
|
||||
<constant>NULL</constant> that will match pointers before it
|
||||
matches integers.
|
||||
<para>
|
||||
Scott Meyers explains this in more detail in his book
|
||||
<link xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xlink:href="https://www.aristeia.com/books.html"><emphasis>Effective
|
||||
Modern C++</emphasis></link> and as a guideline to solve this problem
|
||||
recommends to not overload on pointer-vs-integer types to begin with.
|
||||
</para>
|
||||
<para>See the
|
||||
<link xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xlink:href="http://www.aristeia.com/books.html"><emphasis>Effective
|
||||
C++ CD</emphasis></link> example.
|
||||
|
||||
<para>
|
||||
The C++ 2011 standard added the <constant>nullptr</constant> keyword,
|
||||
which is a null pointer constant of a special type,
|
||||
<classname>std::nullptr_t</classname>. Values of this type can be
|
||||
implicitly converted to <emphasis>any</emphasis> pointer type,
|
||||
and cannot convert to integer types or be deduced as an integer type.
|
||||
Unless you need to be compatible with C++98/C++03 or C you should prefer
|
||||
to use <constant>nullptr</constant> instead of <constant>NULL</constant>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
|
@ -188,59 +194,157 @@
|
|||
|
||||
<section xml:id="std.support.memory" xreflabel="Dynamic Memory"><info><title>Dynamic Memory</title></info>
|
||||
<?dbhtml filename="dynamic_memory.html"?>
|
||||
|
||||
|
||||
<para>
|
||||
There are six flavors each of <function>new</function> and
|
||||
<function>delete</function>, so make certain that you're using the right
|
||||
ones. Here are quickie descriptions of <function>new</function>:
|
||||
In C++98 there are six flavors each of <function>operator new</function>
|
||||
and <function>operator delete</function>, so make certain that you're
|
||||
using the right ones.
|
||||
Here are quickie descriptions of <function>operator new</function>:
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
single object form, throwing a
|
||||
<classname>bad_alloc</classname> on errors; this is what most
|
||||
people are used to using
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
Single object "nothrow" form, returning NULL on errors
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
Array <function>new</function>, throwing
|
||||
<classname>bad_alloc</classname> on errors
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
Array nothrow <function>new</function>, returning
|
||||
<constant>NULL</constant> on errors
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
Placement <function>new</function>, which does nothing (like
|
||||
it's supposed to)
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
Placement array <function>new</function>, which also does
|
||||
nothing
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><code>void* operator new(std::size_t);</code></term>
|
||||
<listitem>
|
||||
Single object form.
|
||||
Throws <classname>std::bad_alloc</classname> on error.
|
||||
This is what most people are used to using.
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><code>void* operator new(std::size_t, std::nothrow_t) noexcept;</code></term>
|
||||
<listitem>
|
||||
Single object <quote>nothrow</quote> form.
|
||||
Calls <code>operator new(std::size_t)</code> but if that throws,
|
||||
returns a null pointer instead.
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><code>void* operator new[](std::size_t);</code></term>
|
||||
<listitem>
|
||||
Array <function>new</function>.
|
||||
Calls <code>operator new(std::size_t)</code> and so
|
||||
throws <classname>std::bad_alloc</classname> on error.
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><code>void* operator new[](std::size_t, std::nothrow_t) noexcept;</code></term>
|
||||
<listitem>
|
||||
Array <quote>nothrow</quote> <function>new</function>.
|
||||
Calls <code>operator new[](std::size_t)</code> but if that throws,
|
||||
returns a null pointer instead.
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><code>void* operator new(std::size_t, void*) noexcept;</code></term>
|
||||
<listitem>
|
||||
Non-allocating, <quote>placement</quote> single-object <function>new</function>,
|
||||
which does nothing except return its argument.
|
||||
This function cannot be replaced.
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><code>void* operator new[](std::size_t, void*) noexcept;</code></term>
|
||||
<listitem>
|
||||
Non-allocating, <quote>placement</quote> array <function>new</function>,
|
||||
which also does nothing except return its argument.
|
||||
This function cannot be replaced.
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
<para>
|
||||
They are distinguished by the parameters that you pass to them, like
|
||||
any other overloaded function. The six flavors of <function>delete</function>
|
||||
They are distinguished by the arguments that you pass to them, like
|
||||
any other overloaded function. The six flavors of
|
||||
<function>operator delete</function>
|
||||
are distinguished the same way, but none of them are allowed to throw
|
||||
an exception under any circumstances anyhow. (They match up for
|
||||
completeness' sake.)
|
||||
an exception under any circumstances anyhow. (The overloads match up
|
||||
with the ones above, for completeness' sake.)
|
||||
</para>
|
||||
<para>
|
||||
Remember that it is perfectly okay to call <function>delete</function> on a
|
||||
NULL pointer! Nothing happens, by definition. That is not the
|
||||
same thing as deleting a pointer twice.
|
||||
The C++ 2014 revision of the standard added two additional overloads of
|
||||
<function>operator delete</function> for <quote>sized deallocation</quote>,
|
||||
allowing the compiler to provide the size of the storage being freed.
|
||||
</para>
|
||||
<para>
|
||||
By default, if one of the <quote>throwing <function>new</function>s</quote> can't
|
||||
allocate the memory requested, it tosses an instance of a
|
||||
<classname>bad_alloc</classname> exception (or, technically, some class derived
|
||||
from it). You can change this by writing your own function (called a
|
||||
new-handler) and then registering it with <function>set_new_handler()</function>:
|
||||
The C++ 2017 standard added even more overloads of both
|
||||
<function>operator new</function> and <function>operator delete</function>
|
||||
for allocating and deallocating storage for overaligned types.
|
||||
These overloads correspond to each of the allocating forms of
|
||||
<function>operator new</function> and <function>operator delete</function>
|
||||
but with an additional parameter of type <type>std::align_val_t</type>.
|
||||
These new overloads are not interchangeable with the versions without
|
||||
an aligment parameter, so if memory was allocated by an overload of
|
||||
<function>operator new</function> taking an alignment parameter,
|
||||
then it must be decallocated by the corresponding overload of
|
||||
<function>operator delete</function> that takes an alignment parameter.
|
||||
</para>
|
||||
<para>
|
||||
Apart from the non-allocating forms, the default versions of the array
|
||||
and nothrow <function>operator new</function> functions will all result
|
||||
in a call to either <function>operator new(std::size_t)</function> or
|
||||
<function>operator new(std::size_t, std::align_val_t)</function>,
|
||||
and similarly the default versions of the array and nothrow
|
||||
<function>operator delete</function> functions will result in a call to
|
||||
either <function>operator delete(void*)</function> or
|
||||
<function>operator delete(void*, std::align_val_t)</function>
|
||||
(or the sized versions of those).
|
||||
</para>
|
||||
<para>
|
||||
Apart from the non-allocating forms, any of these functions can be
|
||||
replaced by defining a function with the same signature in your program.
|
||||
Replacement versions must preserve certain guarantees, such as memory
|
||||
obtained from a nothrow <function>operator new</function> being free-able
|
||||
by the normal (non-nothrow) <function>operator delete</function>,
|
||||
and the sized and unsized forms of <function>operator delete</function>
|
||||
being interchangeable (because it's unspecified whether
|
||||
the compiler calls the sized delete instead of the normal one).
|
||||
The simplest way to meet the guarantees is to only replace the ordinary
|
||||
<function>operator new(size_t)</function> and
|
||||
<function>operator delete(void*)</function> and
|
||||
<function>operator delete(void*, std::size_t)</function>
|
||||
functions, and the replaced versions will be used by all of
|
||||
<function>operator new(size_t, nothrow_t)</function>,
|
||||
<function>operator new[](size_t)</function> and
|
||||
<function>operator new[](size_t, nothrow_t)</function>
|
||||
and the corresponding <function>operator delete</function> functions.
|
||||
To support types with extended alignment you may also need to replace
|
||||
<function>operator new(size_t, align_val_t)</function> and
|
||||
<function>operator delete(void*, align_val_t)</function>
|
||||
<function>operator delete(void*, size_t, align_val_t)</function>
|
||||
(which will then be used by the nothrow and array forms for
|
||||
extended alignments).
|
||||
If you do need to replace other forms (e.g. to define the nothrow
|
||||
<function>operator new</function> to allocate memory directly, so it
|
||||
works with exceptions disabled) then make sure the memory it allocates
|
||||
can still be freed by the non-nothrow forms of
|
||||
<function>operator delete</function>.
|
||||
</para>
|
||||
<para>
|
||||
If the default versions of <function>operator new(std::size_t)</function>
|
||||
and <function>operator new(size_t, std::align_val_t)</function>
|
||||
can't allocate the memory requested, they usually throw an exception
|
||||
object of type <classname>std::bad_alloc</classname> (or some class
|
||||
derived from that). However, the program can influence that behavior
|
||||
by registering a <quote>new-handler</quote>, because what
|
||||
<function>operator new</function> actually does is something like:
|
||||
</para>
|
||||
<programlisting>
|
||||
typedef void (*PFV)(void);
|
||||
while (true)
|
||||
{
|
||||
if (void* p = /* try to allocate memory */)
|
||||
return p;
|
||||
else if (std::new_handler h = std::get_new_handler ())
|
||||
h ();
|
||||
else
|
||||
throw bad_alloc{};
|
||||
}
|
||||
</programlisting>
|
||||
<para>
|
||||
This means you can influence what happens on allocation failure by
|
||||
writing your own new-handler and then registering it with
|
||||
<function>std::set_new_handler</function>:
|
||||
</para>
|
||||
<programlisting>
|
||||
typedef void (*PFV)();
|
||||
|
||||
static char* safety;
|
||||
static PFV old_handler;
|
||||
|
@ -248,6 +352,7 @@
|
|||
void my_new_handler ()
|
||||
{
|
||||
delete[] safety;
|
||||
safety = nullptr;
|
||||
popup_window ("Dude, you are running low on heap memory. You"
|
||||
" should, like, close some windows, or something."
|
||||
" The next time you run out, we're gonna burn!");
|
||||
|
@ -262,19 +367,32 @@
|
|||
...
|
||||
}
|
||||
</programlisting>
|
||||
|
||||
<section xml:id="std.support.memory.notes" xreflabel="Dynamic Memory Notes"><info><title>Additional Notes</title></info>
|
||||
|
||||
<para>
|
||||
<classname>bad_alloc</classname> is derived from the base <classname>exception</classname>
|
||||
class defined in Sect1 19.
|
||||
Remember that it is perfectly okay to <function>delete</function> a
|
||||
null pointer! Nothing happens, by definition. That is not the
|
||||
same thing as deleting a pointer twice.
|
||||
</para>
|
||||
<para>
|
||||
<classname>std::bad_alloc</classname> is derived from the base
|
||||
<classname>std::exception</classname> class,
|
||||
see <xref linkend="std.diagnostics.exceptions"/>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
<section xml:id="std.support.termination" xreflabel="Termination"><info><title>Termination</title></info>
|
||||
<?dbhtml filename="termination.html"?>
|
||||
|
||||
|
||||
<section xml:id="support.termination.handlers" xreflabel="Termination Handlers"><info><title>Termination Handlers</title></info>
|
||||
|
||||
|
||||
<para>
|
||||
Not many changes here to <filename class="headerfile">cstdlib</filename>. You should note that the
|
||||
Not many changes here to
|
||||
<filename class="headerfile"><cstdlib></filename>.
|
||||
You should note that the
|
||||
<function>abort()</function> function does not call the
|
||||
destructors of automatic nor static objects, so if you're
|
||||
depending on those to do cleanup, it isn't going to happen.
|
||||
|
@ -306,8 +424,8 @@
|
|||
given this pseudocode:
|
||||
</para>
|
||||
<programlisting>
|
||||
extern "C or C++" void f1 (void);
|
||||
extern "C or C++" void f2 (void);
|
||||
extern "C or C++" void f1 ();
|
||||
extern "C or C++" void f2 ();
|
||||
|
||||
static Thing obj1;
|
||||
atexit(f1);
|
||||
|
@ -329,19 +447,30 @@
|
|||
Note also that <function>atexit()</function> is only required to store 32
|
||||
functions, and the compiler/library might already be using some of
|
||||
those slots. If you think you may run out, we recommend using
|
||||
the <function>xatexit</function>/<function>xexit</function> combination from <literal>libiberty</literal>, which has no such limit.
|
||||
the <function>xatexit</function>/<function>xexit</function> combination
|
||||
from <literal>libiberty</literal>, which has no such limit.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="support.termination.verbose" xreflabel="Verbose Terminate Handler"><info><title>Verbose Terminate Handler</title></info>
|
||||
<?dbhtml filename="verbose_termination.html"?>
|
||||
|
||||
|
||||
<para>
|
||||
If you are having difficulty with uncaught exceptions and want a
|
||||
little bit of help debugging the causes of the core dumps, you can
|
||||
make use of a GNU extension, the verbose terminate handler.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The verbose terminate handler is only available for hosted environments
|
||||
(see <xref linkend="manual.intro.setup.configure"/>) and will be used
|
||||
by default unless the library is built with
|
||||
<option>--disable-libstdcxx-verbose</option>
|
||||
or with exceptions disabled.
|
||||
If you need to enable it explicitly you can do so by calling the
|
||||
<function>std::set_terminate</function> function.
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
#include <exception>
|
||||
|
||||
|
@ -357,14 +486,15 @@ int main()
|
|||
<para>
|
||||
The <function>__verbose_terminate_handler</function> function
|
||||
obtains the name of the current exception, attempts to demangle
|
||||
it, and prints it to stderr. If the exception is derived from
|
||||
<classname>exception</classname> then the output from
|
||||
it, and prints it to <literal>stderr</literal>.
|
||||
If the exception is derived from
|
||||
<classname>std::exception</classname> then the output from
|
||||
<function>what()</function> will be included.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Any replacement termination function is required to kill the
|
||||
program without returning; this one calls abort.
|
||||
program without returning; this one calls <function>std::abort</function>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
|
@ -407,15 +537,16 @@ int main(int argc)
|
|||
</screen>
|
||||
|
||||
<para>
|
||||
The 'Aborted' line comes from the call to
|
||||
<function>abort()</function>, of course.
|
||||
The 'Aborted' line is printed by the shell after the process exits
|
||||
by calling <function>abort()</function>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
This is the default termination handler; nothing need be done to
|
||||
As this is the default termination handler, nothing need be done to
|
||||
use it. To go back to the previous <quote>silent death</quote>
|
||||
method, simply include <filename>exception</filename> and
|
||||
<filename>cstdlib</filename>, and call
|
||||
method, simply include
|
||||
<filename class="headerfile"><exception></filename> and
|
||||
<filename class="headerfile"><cstdlib></filename>, and call
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
|
@ -429,8 +560,8 @@ int main(int argc)
|
|||
|
||||
<para>
|
||||
Note: the verbose terminate handler will attempt to write to
|
||||
stderr. If your application closes stderr or redirects it to an
|
||||
inappropriate location,
|
||||
<literal>stderr</literal>. If your application closes
|
||||
<literal>stderr</literal> or redirects it to an inappropriate location,
|
||||
<function>__verbose_terminate_handler</function> will behave in
|
||||
an unspecified manner.
|
||||
</para>
|
||||
|
|
Loading…
Reference in New Issue