641 lines
29 KiB
HTML
641 lines
29 KiB
HTML
|
<!DOCTYPE html>
|
||
|
<html>
|
||
|
<head>
|
||
|
<meta charset="utf-8">
|
||
|
<meta content="IE=edge" http-equiv="X-UA-Compatible">
|
||
|
<meta content="width=device-width, initial-scale=1.0" name="viewport">
|
||
|
<title>Defensive Coding Guide | Defensive Coding Guide | Programming Languages | The C++ Programming Language</title>
|
||
|
|
||
|
<!-- Bootstrap -->
|
||
|
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
|
||
|
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
|
||
|
|
||
|
<!-- Overpass Font -->
|
||
|
<link rel="stylesheet" href="https://overpass-30e2.kxcdn.com/overpass.css">
|
||
|
|
||
|
<link href="../../../master/_stylesheets/asciibinder.css" rel="stylesheet" />
|
||
|
|
||
|
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
|
||
|
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
|
||
|
<!--[if lt IE 9]>
|
||
|
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
|
||
|
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
|
||
|
<![endif]-->
|
||
|
|
||
|
<link href="../../../master/_images/favicon32x32.png" rel="shortcut icon" type="text/css">
|
||
|
<!--[if IE]><link rel="shortcut icon" href="../../../master/_images/favicon.ico"><![endif]-->
|
||
|
<meta content="AsciiBinder" name="application-name">
|
||
|
</head>
|
||
|
<body>
|
||
|
<div class="navbar navbar-default" role="navigation">
|
||
|
<div class="container-fluid">
|
||
|
<div class="navbar-header">
|
||
|
<a class="navbar-brand" href="https://docs.fedoraproject.org/"><img alt="Fedora Documentation" src="../../../master/_images/fedora.svg"></a>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="container">
|
||
|
<p class="toggle-nav visible-xs pull-left">
|
||
|
<button class="btn btn-default btn-sm" type="button" data-toggle="offcanvas">Toggle nav</button>
|
||
|
</p>
|
||
|
<ol class="breadcrumb">
|
||
|
<li class="sitename">
|
||
|
<a href="../../../index.html">Home</a>
|
||
|
</li>
|
||
|
<li class="hidden-xs active">
|
||
|
<a href="../../en-US/index.html">Defensive Coding Guide </a>
|
||
|
</li>
|
||
|
<li class="hidden-xs active">
|
||
|
<a href="../../en-US/index.html">Defensive Coding Guide</a>
|
||
|
</li>
|
||
|
<li class="hidden-xs active"><a href="../../en-US/programming-languages/C.html">Programming Languages</a></li>
|
||
|
<li class="hidden-xs active">
|
||
|
The C++ Programming Language
|
||
|
</li>
|
||
|
</ol>
|
||
|
<div class="row row-offcanvas row-offcanvas-left">
|
||
|
<div class="col-xs-8 col-sm-3 col-md-3 sidebar sidebar-offcanvas">
|
||
|
<ul class="nav nav-sidebar">
|
||
|
<li class="nav-header">
|
||
|
<a class="" href="#" data-toggle="collapse" data-target="#topicGroup0">
|
||
|
<span id="tgSpan0" class="fa fa-angle-down"></span>Defensive Coding Guide
|
||
|
</a>
|
||
|
<ul id="topicGroup0" class="collapse in list-unstyled">
|
||
|
<li><a class="" href="../../en-US/index.html">Book Information</a></li>
|
||
|
<li class="nav-header">
|
||
|
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-1">
|
||
|
<span id="sgSpan-0-1" class="fa fa-caret-down"></span> Programming Languages
|
||
|
</a>
|
||
|
<ul id="topicSubGroup-0-1" class="nav-tertiary list-unstyled collapse in">
|
||
|
<li><a class="" href="../../en-US/programming-languages/C.html">The C Programming Language</a></li>
|
||
|
<li><a class=" active" href="../../en-US/programming-languages/CXX.html">The C++ Programming Language</a></li>
|
||
|
<li><a class="" href="../../en-US/programming-languages/Java.html">The Java Programming Language</a></li>
|
||
|
<li><a class="" href="../../en-US/programming-languages/Python.html">The Python Programming Language</a></li>
|
||
|
<li><a class="" href="../../en-US/programming-languages/Shell.html">Shell Programming and bash</a></li>
|
||
|
<li><a class="" href="../../en-US/programming-languages/Go.html">The Go Programming Language</a></li>
|
||
|
<li><a class="" href="../../en-US/programming-languages/Vala.html">The Vala Programming Language</a></li>
|
||
|
</ul>
|
||
|
</li>
|
||
|
<li class="nav-header">
|
||
|
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-2">
|
||
|
<span id="sgSpan-0-2" class="fa fa-caret-right"></span> Specific Programming Tasks
|
||
|
</a>
|
||
|
<ul id="topicSubGroup-0-2" class="nav-tertiary list-unstyled collapse">
|
||
|
<li><a class="" href="../../en-US/tasks/Tasks-Library_Design.html">Library Design</a></li>
|
||
|
<li><a class="" href="../../en-US/tasks/Tasks-Descriptors.html">File Descriptor Management</a></li>
|
||
|
<li><a class="" href="../../en-US/tasks/Tasks-File_System.html">File System Manipulation</a></li>
|
||
|
<li><a class="" href="../../en-US/tasks/Tasks-Temporary_Files.html">Temporary Files</a></li>
|
||
|
<li><a class="" href="../../en-US/tasks/Tasks-Processes.html">Processes</a></li>
|
||
|
<li><a class="" href="../../en-US/tasks/Tasks-Serialization.html">Serialization and Deserialization</a></li>
|
||
|
<li><a class="" href="../../en-US/tasks/Tasks-Cryptography.html">Cryptography</a></li>
|
||
|
<li><a class="" href="../../en-US/tasks/Tasks-Packaging.html">RPM Packaging</a></li>
|
||
|
</ul>
|
||
|
</li>
|
||
|
<li class="nav-header">
|
||
|
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-3">
|
||
|
<span id="sgSpan-0-3" class="fa fa-caret-right"></span> Implementing Security Features
|
||
|
</a>
|
||
|
<ul id="topicSubGroup-0-3" class="nav-tertiary list-unstyled collapse">
|
||
|
<li><a class="" href="../../en-US/features/Features-Authentication.html">Authentication and Authorization</a></li>
|
||
|
<li><a class="" href="../../en-US/features/Features-TLS.html">Transport Layer Security (TLS)</a></li>
|
||
|
<li><a class="" href="../../en-US/features/Features-HSM.html">Hardware Security Modules and Smart Cards</a></li>
|
||
|
</ul>
|
||
|
</li>
|
||
|
<li><a class="" href="../../en-US/Revision_History.html">Revision History</a></li>
|
||
|
</ul>
|
||
|
</li>
|
||
|
</ul>
|
||
|
</div>
|
||
|
<div class="col-xs-12 col-sm-9 col-md-9 main">
|
||
|
<div class="page-header">
|
||
|
<h2>The C++ Programming Language</h2>
|
||
|
</div>
|
||
|
<div class="sect1">
|
||
|
<h2 id="sect-Defensive_Coding-CXX-Language"><a class="anchor" href="#sect-Defensive_Coding-CXX-Language"></a>The Core Language</h2>
|
||
|
<div class="sectionbody">
|
||
|
<div class="paragraph">
|
||
|
<p>C++ includes a large subset of the C language. As far as the C
|
||
|
subset is used, the recommendations in <a href="#chap-Defensive_Coding-C">[chap-Defensive_Coding-C]</a> apply.</p>
|
||
|
</div>
|
||
|
<div class="sect2">
|
||
|
<h3 id="array-allocation-with-code-operator-new-code"><a class="anchor" href="#array-allocation-with-code-operator-new-code"></a>Array Allocation with <code>operator new[]</code></h3>
|
||
|
<div class="paragraph">
|
||
|
<p>For very large values of <code>n</code>, an expression
|
||
|
like <code>new T[n]</code> can return a pointer to a heap
|
||
|
region which is too small. In other words, not all array
|
||
|
elements are actually backed with heap memory reserved to the
|
||
|
array. Current GCC versions generate code that performs a
|
||
|
computation of the form <code>sizeof(T) * size_t(n)<br>
|
||
|
cookie_size</code>, where <code>cookie_size</code> is
|
||
|
currently at most 8. This computation can overflow, and GCC
|
||
|
versions prior to 4.8 generated code which did not detect this.
|
||
|
(Fedora 18 was the first release which fixed this in GCC.)</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>The <code>std::vector</code> template can be used instead
|
||
|
an explicit array allocation. (The GCC implementation detects
|
||
|
overflow internally.)</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>If there is no alternative to <code>operator new[]</code>
|
||
|
and the sources will be compiled with older GCC versions, code
|
||
|
which allocates arrays with a variable length must check for
|
||
|
overflow manually. For the <code>new T[n]</code> example,
|
||
|
the size check could be <code>n || (n > 0 && n >
|
||
|
(size_t(-1) - 8) / sizeof(T))</code>. (See <a href="#sect-Defensive_Coding-C-Arithmetic">[sect-Defensive_Coding-C-Arithmetic]</a>.) If there are
|
||
|
additional dimensions (which must be constants according to the
|
||
|
C++ standard), these should be included as factors in the
|
||
|
divisor.</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>These countermeasures prevent out-of-bounds writes and potential
|
||
|
code execution. Very large memory allocations can still lead to
|
||
|
a denial of service. <a href="#sect-Defensive_Coding-Tasks-Serialization-Decoders">[sect-Defensive_Coding-Tasks-Serialization-Decoders]</a>
|
||
|
contains suggestions for mitigating this problem when processing
|
||
|
untrusted data.</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>See <a href="#sect-Defensive_Coding-C-Allocators-Arrays">[sect-Defensive_Coding-C-Allocators-Arrays]</a>
|
||
|
for array allocation advice for C-style memory allocation.</p>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="sect2">
|
||
|
<h3 id="overloading"><a class="anchor" href="#overloading"></a>Overloading</h3>
|
||
|
<div class="paragraph">
|
||
|
<p>Do not overload functions with versions that have different
|
||
|
security characteristics. For instance, do not implement a
|
||
|
function <code>strcat</code> which works on
|
||
|
<code>std::string</code> arguments. Similarly, do not name
|
||
|
methods after such functions.</p>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="sect2">
|
||
|
<h3 id="abi-compatibility-and-preparing-for-security-updates"><a class="anchor" href="#abi-compatibility-and-preparing-for-security-updates"></a>ABI compatibility and preparing for security updates</h3>
|
||
|
<div class="paragraph">
|
||
|
<p>A stable binary interface (ABI) is vastly preferred for security
|
||
|
updates. Without a stable ABI, all reverse dependencies need
|
||
|
recompiling, which can be a lot of work and could even be
|
||
|
impossible in some cases. Ideally, a security update only
|
||
|
updates a single dynamic shared object, and is picked up
|
||
|
automatically after restarting affected processes.</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>Outside of extremely performance-critical code, you should
|
||
|
ensure that a wide range of changes is possible without breaking
|
||
|
ABI. Some very basic guidelines are:</p>
|
||
|
</div>
|
||
|
<div class="ulist">
|
||
|
<ul>
|
||
|
<li>
|
||
|
<p>Avoid inline functions.</p>
|
||
|
</li>
|
||
|
<li>
|
||
|
<p>Use the pointer-to-implementation idiom.</p>
|
||
|
</li>
|
||
|
<li>
|
||
|
<p>Try to avoid templates. Use them if the increased type
|
||
|
safety provides a benefit to the programmer.</p>
|
||
|
</li>
|
||
|
<li>
|
||
|
<p>Move security-critical code out of templated code, so that
|
||
|
it can be patched in a central place if necessary.</p>
|
||
|
</li>
|
||
|
</ul>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>The KDE project publishes a document with more extensive
|
||
|
guidelines on ABI-preserving changes to C++ code, <a href="https://community.kde.org/Policies/Binary_Compatibility_Issues_With_C%2B%2B">Policies/Binary
|
||
|
Compatibility Issues With C++</a>
|
||
|
(<strong>d-pointer</strong> refers to the
|
||
|
pointer-to-implementation idiom).</p>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="sect2">
|
||
|
<h3 id="sect-Defensive_Coding-CXX-Language-CXX11"><a class="anchor" href="#sect-Defensive_Coding-CXX-Language-CXX11"></a>C++0X and C++11 Support</h3>
|
||
|
<div class="paragraph">
|
||
|
<p>GCC offers different language compatibility modes:</p>
|
||
|
</div>
|
||
|
<div class="ulist">
|
||
|
<ul>
|
||
|
<li>
|
||
|
<p><code class="option">-std=c++98</code> for the original 1998 C++
|
||
|
standard</p>
|
||
|
</li>
|
||
|
<li>
|
||
|
<p><code class="option">-std=c++03</code> for the 1998 standard with the
|
||
|
changes from the TR1 technical report</p>
|
||
|
</li>
|
||
|
<li>
|
||
|
<p><code class="option">-std=c++11</code> for the 2011 C++ standard. This
|
||
|
option should not be used.</p>
|
||
|
</li>
|
||
|
<li>
|
||
|
<p><code class="option">-std=c++0x</code> for several different versions
|
||
|
of C++11 support in development, depending on the GCC
|
||
|
version. This option should not be used.</p>
|
||
|
</li>
|
||
|
</ul>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>For each of these flags, there are variants which also enable
|
||
|
GNU extensions (mostly language features also found in C99 or
|
||
|
C11):</p>
|
||
|
</div>
|
||
|
<div class="ulist">
|
||
|
<ul>
|
||
|
<li>
|
||
|
<p><code class="option">-std=gnu++98</code></p>
|
||
|
</li>
|
||
|
<li>
|
||
|
<p><code class="option">-std=gnu++03</code></p>
|
||
|
</li>
|
||
|
<li>
|
||
|
<p><code class="option">-std=gnu++11</code></p>
|
||
|
</li>
|
||
|
</ul>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>Again, <code class="option">-std=gnu++11</code> should not be used.</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>If you enable C++11 support, the ABI of the standard C++ library
|
||
|
<code>libstdc++</code> will change in subtle ways.
|
||
|
Currently, no C++ libraries are compiled in C++11 mode, so if
|
||
|
you compile your code in C++11 mode, it will be incompatible
|
||
|
with the rest of the system. Unfortunately, this is also the
|
||
|
case if you do not use any C++11 features. Currently, there is
|
||
|
no safe way to enable C++11 mode (except for freestanding
|
||
|
applications).</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>The meaning of C++0X mode changed from GCC release to GCC
|
||
|
release. Earlier versions were still ABI-compatible with C++98
|
||
|
mode, but in the most recent versions, switching to C++0X mode
|
||
|
activates C++11 support, with its compatibility problems.</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>Some C++11 features (or approximations thereof) are available
|
||
|
with TR1 support, that is, with <code class="option">-std=c03` or
|
||
|
[option]`-std=gnu03</code> and in the
|
||
|
<code><tr1/*></code> header files. This includes
|
||
|
<code>std::tr1::shared_ptr</code> (from
|
||
|
<code><tr1/memory></code>) and
|
||
|
<code>std::tr1::function</code> (from
|
||
|
<code><tr1/functional></code>). For other C++11
|
||
|
features, the Boost C++ library contains replacements.</p>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="sect1">
|
||
|
<h2 id="sect-Defensive_Coding-CXX-Std"><a class="anchor" href="#sect-Defensive_Coding-CXX-Std"></a>The C++ Standard Library</h2>
|
||
|
<div class="sectionbody">
|
||
|
<div class="paragraph">
|
||
|
<p>The C++ standard library includes most of its C counterpart
|
||
|
by reference, see <a href="#sect-Defensive_Coding-C-Libc">[sect-Defensive_Coding-C-Libc]</a>.</p>
|
||
|
</div>
|
||
|
<div class="sect2">
|
||
|
<h3 id="sect-Defensive_Coding-CXX-Std-Functions"><a class="anchor" href="#sect-Defensive_Coding-CXX-Std-Functions"></a>Functions That Are Difficult to Use</h3>
|
||
|
<div class="paragraph">
|
||
|
<p>This section collects functions and function templates which are
|
||
|
part of the standard library and are difficult to use.</p>
|
||
|
</div>
|
||
|
<div class="sect3">
|
||
|
<h4 id="sect-Defensive_Coding-CXX-Std-Functions-Unpaired_Iterators"><a class="anchor" href="#sect-Defensive_Coding-CXX-Std-Functions-Unpaired_Iterators"></a>Unpaired Iterators</h4>
|
||
|
<div class="paragraph">
|
||
|
<p>Functions which use output operators or iterators which do not
|
||
|
come in pairs (denoting ranges) cannot perform iterator range
|
||
|
checking.
|
||
|
(See <a href="#sect-Defensive_Coding-CXX-Std-Iterators">Iterators</a>)
|
||
|
Function templates which involve output iterators are
|
||
|
particularly dangerous:</p>
|
||
|
</div>
|
||
|
<div class="ulist">
|
||
|
<ul>
|
||
|
<li>
|
||
|
<p><code>std::copy</code></p>
|
||
|
</li>
|
||
|
<li>
|
||
|
<p><code>std::copy_backward</code></p>
|
||
|
</li>
|
||
|
<li>
|
||
|
<p><code>std::copy_if</code></p>
|
||
|
</li>
|
||
|
<li>
|
||
|
<p><code>std::move</code> (three-argument variant)</p>
|
||
|
</li>
|
||
|
<li>
|
||
|
<p><code>std::move_backward</code></p>
|
||
|
</li>
|
||
|
<li>
|
||
|
<p><code>std::partition_copy_if</code></p>
|
||
|
</li>
|
||
|
<li>
|
||
|
<p><code>std::remove_copy</code></p>
|
||
|
</li>
|
||
|
<li>
|
||
|
<p><code>std::remove_copy_if</code></p>
|
||
|
</li>
|
||
|
<li>
|
||
|
<p><code>std::replace_copy</code></p>
|
||
|
</li>
|
||
|
<li>
|
||
|
<p><code>std::replace_copy_if</code></p>
|
||
|
</li>
|
||
|
<li>
|
||
|
<p><code>std::swap_ranges</code></p>
|
||
|
</li>
|
||
|
<li>
|
||
|
<p><code>std::transform</code></p>
|
||
|
</li>
|
||
|
</ul>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>In addition, <code>std::copy_n</code>,
|
||
|
<code>std::fill_n</code> and
|
||
|
<code>std::generate_n</code> do not perform iterator
|
||
|
checking, either, but there is an explicit count which has to be
|
||
|
supplied by the caller, as opposed to an implicit length
|
||
|
indicator in the form of a pair of forward iterators.</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>These output-iterator-expecting functions should only be used
|
||
|
with unlimited-range output iterators, such as iterators
|
||
|
obtained with the <code>std::back_inserter</code>
|
||
|
function.</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>Other functions use single input or forward iterators, which can
|
||
|
read beyond the end of the input range if the caller is not careful:</p>
|
||
|
</div>
|
||
|
<div class="ulist">
|
||
|
<ul>
|
||
|
<li>
|
||
|
<p><code>std::equal</code></p>
|
||
|
</li>
|
||
|
<li>
|
||
|
<p><code>std::is_permutation</code></p>
|
||
|
</li>
|
||
|
<li>
|
||
|
<p><code>std::mismatch</code></p>
|
||
|
</li>
|
||
|
</ul>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="sect2">
|
||
|
<h3 id="sect-Defensive_Coding-CXX-Std-String"><a class="anchor" href="#sect-Defensive_Coding-CXX-Std-String"></a>String Handling with <code>std::string</code></h3>
|
||
|
<div class="paragraph">
|
||
|
<p>The <code>std::string</code> class provides a convenient
|
||
|
way to handle strings. Unlike C strings,
|
||
|
<code>std::string</code> objects have an explicit length
|
||
|
(and can contain embedded NUL characters), and storage for its
|
||
|
characters is managed automatically. This section discusses
|
||
|
<code>std::string</code>, but these observations also
|
||
|
apply to other instances of the
|
||
|
<code>std::basic_string</code> template.</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>The pointer returned by the <code>data()</code> member
|
||
|
function does not necessarily point to a NUL-terminated string.
|
||
|
To obtain a C-compatible string pointer, use
|
||
|
<code>c_str()</code> instead, which adds the NUL
|
||
|
terminator.</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>The pointers returned by the <code>data()</code> and
|
||
|
<code>c_str()</code> functions and iterators are only
|
||
|
valid until certain events happen. It is required that the
|
||
|
exact <code>std::string</code> object still exists (even
|
||
|
if it was initially created as a copy of another string object).
|
||
|
Pointers and iterators are also invalidated when non-const
|
||
|
member functions are called, or functions with a non-const
|
||
|
reference parameter. The behavior of the GCC implementation
|
||
|
deviates from that required by the C++ standard if multiple
|
||
|
threads are present. In general, only the first call to a
|
||
|
non-const member function after a structural modification of the
|
||
|
string (such as appending a character) is invalidating, but this
|
||
|
also applies to member function such as the non-const version of
|
||
|
<code>begin()</code>, in violation of the C++ standard.</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>Particular care is necessary when invoking the
|
||
|
<code>c_str()</code> member function on a temporary
|
||
|
object. This is convenient for calling C functions, but the
|
||
|
pointer will turn invalid as soon as the temporary object is
|
||
|
destroyed, which generally happens when the outermost expression
|
||
|
enclosing the expression on which <code>c_str()</code>
|
||
|
is called completes evaluation. Passing the result of
|
||
|
<code>c_str()</code> to a function which does not store
|
||
|
or otherwise leak that pointer is safe, though.</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>Like with <code>std::vector</code> and
|
||
|
<code>std::array</code>, subscribing with
|
||
|
<code>operator[]</code> does not perform bounds checks.
|
||
|
Use the <code>at(size_type)</code> member function
|
||
|
instead. See <a href="#sect-Defensive_Coding-CXX-Std-Subscript">Containers and <code>operator[]</code></a>.
|
||
|
Furthermore, accessing the terminating NUL character using
|
||
|
<code>operator[]</code> is not possible. (In some
|
||
|
implementations, the <code>c_str()</code> member function
|
||
|
writes the NUL character on demand.)</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>Never write to the pointers returned by
|
||
|
<code>data()</code> or <code>c_str()</code>
|
||
|
after casting away <code>const</code>. If you need a
|
||
|
C-style writable string, use a
|
||
|
<code>std::vector<char></code> object and its
|
||
|
<code>data()</code> member function. In this case, you
|
||
|
have to explicitly add the terminating NUL character.</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>GCC’s implementation of <code>std::string</code> is
|
||
|
currently based on reference counting. It is expected that a
|
||
|
future version will remove the reference counting, due to
|
||
|
performance and conformance issues. As a result, code that
|
||
|
implicitly assumes sharing by holding to pointers or iterators
|
||
|
for too long will break, resulting in run-time crashes or worse.
|
||
|
On the other hand, non-const iterator-returning functions will
|
||
|
no longer give other threads an opportunity for invalidating
|
||
|
existing iterators and pointers because iterator invalidation
|
||
|
does not depend on sharing of the internal character array
|
||
|
object anymore.</p>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="sect2">
|
||
|
<h3 id="sect-Defensive_Coding-CXX-Std-Subscript"><a class="anchor" href="#sect-Defensive_Coding-CXX-Std-Subscript"></a>Containers and <code>operator[]</code></h3>
|
||
|
<div class="paragraph">
|
||
|
<p>Many sequence containers similar to <code>std::vector</code>
|
||
|
provide both <code>operator[](size_type)</code> and a
|
||
|
member function <code>at(size_type)</code>. This applies
|
||
|
to <code>std::vector</code> itself,
|
||
|
<code>std::array</code>, <code>std::string</code>
|
||
|
and other instances of <code>std::basic_string</code>.</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p><code>operator[](size_type)</code> is not required by the
|
||
|
standard to perform bounds checking (and the implementation in
|
||
|
GCC does not). In contrast, <code>at(size_type)</code>
|
||
|
must perform such a check. Therefore, in code which is not
|
||
|
performance-critical, you should prefer
|
||
|
<code>at(size_type)</code> over
|
||
|
<code>operator[](size_type)</code>, even though it is
|
||
|
slightly more verbose.</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>The <code>front()</code> and <code>back()</code>
|
||
|
member functions are undefined if a vector object is empty. You
|
||
|
can use <code>vec.at(0)</code> and
|
||
|
<code>vec.at(vec.size() - 1)</code> as checked
|
||
|
replacements. For an empty vector, <code>data()</code> is
|
||
|
defined; it returns an arbitrary pointer, but not necessarily
|
||
|
the NULL pointer.</p>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="sect2">
|
||
|
<h3 id="sect-Defensive_Coding-CXX-Std-Iterators"><a class="anchor" href="#sect-Defensive_Coding-CXX-Std-Iterators"></a>Iterators</h3>
|
||
|
<div class="paragraph">
|
||
|
<p>Iterators do not perform any bounds checking. Therefore, all
|
||
|
functions that work on iterators should accept them in pairs,
|
||
|
denoting a range, and make sure that iterators are not moved
|
||
|
outside that range. For forward iterators and bidirectional
|
||
|
iterators, you need to check for equality before moving the
|
||
|
first or last iterator in the range. For random-access
|
||
|
iterators, you need to compute the difference before adding or
|
||
|
subtracting an offset. It is not possible to perform the
|
||
|
operation and check for an invalid operator afterwards.</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>Output iterators cannot be compared for equality. Therefore, it
|
||
|
is impossible to write code that detects that it has been
|
||
|
supplied an output area that is too small, and their use should
|
||
|
be avoided.</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>These issues make some of the standard library functions
|
||
|
difficult to use correctly, see <a href="#sect-Defensive_Coding-CXX-Std-Functions-Unpaired_Iterators">Unpaired Iterators</a>.</p>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div id="bottom" class="text-muted py-3" >
|
||
|
<div class="foot">
|
||
|
<div class="container">
|
||
|
<div class="row footerlinks">
|
||
|
<div class="col-sm-3 col-xs-6 widget">
|
||
|
<h3 class="widget-title">About</h3>
|
||
|
<div class="widget-body">
|
||
|
<dl>
|
||
|
<dd><a href="https://fedoraproject.org/wiki/Overview">About Fedora</a></dd>
|
||
|
<dd><a href="https://getfedora.org/en/sponsors">Sponsors</a></dd>
|
||
|
<dd><a href="https://fedoramagazine.org">Fedora Magazine</a></dd>
|
||
|
<dd><a href="https://fedoraproject.org/wiki/Legal:Main#Legal">Legal</a></dd>
|
||
|
</dl>
|
||
|
<ul class="list-inline">
|
||
|
<li>
|
||
|
<a href="https://www.facebook.com/TheFedoraProject" class="btn-social btn-outline"><i class="fa fa-fw fa-facebook"></i></a>
|
||
|
</li>
|
||
|
<li>
|
||
|
<a href="https://plus.google.com/112917221531140868607" class="btn-social btn-outline"><i class="fa fa-fw fa-google-plus"></i></a>
|
||
|
</li>
|
||
|
<li>
|
||
|
<a href="https://twitter.com/fedora" class="btn-social btn-outline"><i class="fa fa-fw fa-twitter"></i></a>
|
||
|
</li>
|
||
|
</ul>
|
||
|
</div>
|
||
|
</div>
|
||
|
|
||
|
<div class="col-sm-3 col-xs-6 widget">
|
||
|
<h3 class="widget-title uppercase">Download</h3>
|
||
|
<div class="widget-body">
|
||
|
<dl>
|
||
|
<dd><a href="https://getfedora.org/en/workstation/download">Get Fedora Workstation</a></dd>
|
||
|
<dd><a href="https://getfedora.org/en/server/download">Get Fedora Server</a></dd>
|
||
|
<dd><a href="https://getfedora.org/en/atomic/download">Get Fedora Atomic</a></dd>
|
||
|
<dd><a href="https://spins.fedoraproject.org">Fedora Spins</a></dd>
|
||
|
<dd><a href="https://labs.fedoraproject.org">Fedora Labs</a></dd>
|
||
|
<dd><a href="https://arm.fedoraproject.org">Fedora ARM<span class="sup">®</span></a></dd>
|
||
|
<dd><a href="https://alt.fedoraproject.org/">Alternative Downloads</a></dd>
|
||
|
|
||
|
</dl>
|
||
|
</div>
|
||
|
</div>
|
||
|
|
||
|
<div class="col-sm-3 col-xs-6 widget">
|
||
|
<h3 class="widget-title">Support</h3>
|
||
|
<div class="widget-body">
|
||
|
<dl>
|
||
|
<dd><a href="https://fedoraproject.org/wiki/Communicating_and_getting_help">Get Help</a></dd>
|
||
|
<dd><a href="https://ask.fedoraproject.org/">Ask Fedora</a></dd>
|
||
|
<dd><a href="https://fedoraproject.org/wiki/Common_F27_bugs">Common Bugs</a></dd>
|
||
|
<dd><a href="https://developer.fedoraproject.org/">Fedora Developer Portal</a></dd>
|
||
|
<dd><a href="https://docs.fedoraproject.org/f27/install-guide/index.html">Installation Guide</a></dd>
|
||
|
</dl>
|
||
|
</div>
|
||
|
</div>
|
||
|
|
||
|
<div class="col-sm-3 col-xs-6 widget">
|
||
|
<h3 class="widget-title">Join</h3>
|
||
|
<div class="widget-body">
|
||
|
<dl>
|
||
|
<dd><a href="https://fedoraproject.org/wiki/Join">Join Fedora</a></dd>
|
||
|
<dd><a href="http://fedoraplanet.org">Planet Fedora</a></dd>
|
||
|
<dd><a href="https://fedoraproject.org/wiki/SIGs">Fedora SIGs</a></dd>
|
||
|
<dd><a href="https://admin.fedoraproject.org/accounts/">Fedora Account System</a></dd>
|
||
|
<dd><a href="https://fedoracommunity.org/">Fedora Community</a></dd>
|
||
|
</dl>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div> <!-- /row of widgets -->
|
||
|
|
||
|
<div class="row">
|
||
|
<div class="col-md-2">
|
||
|
<div class="widget-body">
|
||
|
<a href="https://www.redhat.com/"><img class="rh-logo" src="../../../master/_images/redhat-logo.png" alt="Red Hat Logo" /></a>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="col-md-7">
|
||
|
<div class="widget-body">
|
||
|
<p class="sponsor">Fedora is sponsored by Red Hat.</p>
|
||
|
<p class="sponsor"><a href="https://www.redhat.com/en/technologies/linux-platforms/articles/relationship-between-fedora-and-rhel">Learn more about the relationship between Red Hat and Fedora »</a></p>
|
||
|
<p class="copy">© 2017 Red Hat, Inc. and others. Please send any comments or corrections to the <a href="https://pagure.io/fedora-docs/docs-fp-o">documentation team</a></p>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div> <!-- /row of widgets -->
|
||
|
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
|
||
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
|
||
|
<!-- Latest compiled and minified JavaScript -->
|
||
|
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
|
||
|
<script src="../../../master/_javascripts/bootstrap-offcanvas.js" type="text/javascript"></script>
|
||
|
<script type="text/javascript">
|
||
|
/*<![CDATA[*/
|
||
|
$(document).ready(function() {
|
||
|
$("[id^='topicGroup']").on('show.bs.collapse', function (event) {
|
||
|
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
|
||
|
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
|
||
|
}
|
||
|
});
|
||
|
$("[id^='topicGroup']").on('hide.bs.collapse', function (event) {
|
||
|
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
|
||
|
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
|
||
|
}
|
||
|
});
|
||
|
$("[id^='topicSubGroup']").on('show.bs.collapse', function () {
|
||
|
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
|
||
|
});
|
||
|
$("[id^='topicSubGroup']").on('hide.bs.collapse', function () {
|
||
|
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
|
||
|
});
|
||
|
});
|
||
|
/*]]>*/
|
||
|
</script>
|
||
|
</body>
|
||
|
</html>
|