<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 526: Is it undefined if a function in the standard changes in parameters?</title>
<meta property="og:title" content="Issue 526: Is it undefined if a function in the standard changes in parameters?">
<meta property="og:description" content="C++ library issue. Status: NAD">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue526.html">
<meta property="og:type" content="website">
<meta property="og:image" content="http://cplusplus.github.io/LWG/images/cpp_logo.png">
<meta property="og:image:alt" content="C++ logo">
<style>
  p {text-align:justify}
  li {text-align:justify}
  pre code.backtick::before { content: "`" }
  pre code.backtick::after { content: "`" }
  blockquote.note
  {
    background-color:#E0E0E0;
    padding-left: 15px;
    padding-right: 15px;
    padding-top: 1px;
    padding-bottom: 1px;
  }
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
  table.issues-index { border: 1px solid; border-collapse: collapse; }
  table.issues-index th { text-align: center; padding: 4px; border: 1px solid; }
  table.issues-index td { padding: 4px; border: 1px solid; }
  table.issues-index td:nth-child(1) { text-align: right; }
  table.issues-index td:nth-child(2) { text-align: left; }
  table.issues-index td:nth-child(3) { text-align: left; }
  table.issues-index td:nth-child(4) { text-align: left; }
  table.issues-index td:nth-child(5) { text-align: center; }
  table.issues-index td:nth-child(6) { text-align: center; }
  table.issues-index td:nth-child(7) { text-align: left; }
  table.issues-index td:nth-child(5) span.no-pr { color: red; }
  @media (prefers-color-scheme: dark) {
     html {
        color: #ddd;
        background-color: black;
     }
     ins {
        background-color: #225522
     }
     del {
        background-color: #662222
     }
     a {
        color: #6af
     }
     a:visited {
        color: #6af
     }
     blockquote.note
     {
        background-color: rgba(255, 255, 255, .10)
     }
  }
</style>
</head>
<body>
<hr>
<p><em>This page is a snapshot from the LWG issues list, see the <a href="lwg-active.html">Library Active Issues List</a> for more information and the meaning of <a href="lwg-active.html#NAD">NAD</a> status.</em></p>
<h3 id="526"><a href="lwg-closed.html#526">526</a>. Is it undefined if a function in the standard changes in parameters?</h3>
<p><b>Section:</b> 23.2.4 <a href="https://wg21.link/sequence.reqmts">[sequence.reqmts]</a> <b>Status:</b> <a href="lwg-active.html#NAD">NAD</a>
 <b>Submitter:</b> Chris Jefferson <b>Opened:</b> 2005-09-14 <b>Last modified:</b> 2016-01-28</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View other</b> <a href="lwg-index-open.html#sequence.reqmts">active issues</a> in [sequence.reqmts].</p>
<p><b>View all other</b> <a href="lwg-index.html#sequence.reqmts">issues</a> in [sequence.reqmts].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#NAD">NAD</a> status.</p>
<p><b>Discussion:</b></p>
<p>
Problem: There are a number of places in the C++ standard library where
it is possible to write what appear to be sensible ways of calling
functions, but which can cause problems in some (or all)
implementations, as they cause the values given to the function to be
changed in a way not specified in standard (and therefore not coded to
correctly work). These fall into two similar categories.
</p>

<p>
1) Parameters taken by const reference can be changed during execution
of the function
</p>

<p>
Examples:
</p>

<p>
Given std::vector&lt;int&gt; v:
</p>
<p>
v.insert(v.begin(), v[2]);
</p>
<p>
v[2] can be changed by moving elements of vector
</p>


<p>
Given std::list&lt;int&gt; l:
</p>
<p>
l.remove(*l.begin());
</p>
<p>
Will delete the first element, and then continue trying to access it.
This is particularily vicious, as it will appear to work in almost all
cases.
</p>

<p>
2) A range is given which changes during the execution of the function:
Similarly,
</p>

<p>
v.insert(v.begin(), v.begin()+4, v.begin()+6);
</p>

<p>
This kind of problem has been partly covered in some cases. For example
std::copy(first, last, result) states that result cannot be in the range
[first, last). However, does this cover the case where result is a
reverse_iterator built from some iterator in the range [first, last)?
Also, std::copy would still break if result was reverse_iterator(last +
1), yet this is not forbidden by the standard
</p>

<p>
Solution:
</p>

<p>
One option would be to try to more carefully limit the requirements of
each function. There are many functions which would have to be checked.
However as has been shown in the std::copy case, this may be difficult.
A simpler, more global option would be to somewhere insert text similar to:
</p>

<p>
If the execution of any function would change either any values passed
by reference or any value in any range passed to a function in a way not
defined in the definition of that function, the result is undefined.
</p>

<p>
Such code would have to at least cover chapters 23 and 25 (the sections
I read through carefully). I can see no harm on applying it to much of
the rest of the standard.
</p>

<p>
Some existing parts of the standard could be improved to fit with this,
for example the requires for 25.2.1 (Copy) could be adjusted to:
</p>

<p>
Requires: For each non-negative integer n &lt; (last - first), assigning to
*(result + n) must not alter any value in the range [first + n, last).
</p>

<p>
However, this may add excessive complication.
</p>

<p>
One other benefit of clearly introducing this text is that it would
allow a number of small optimisations, such as caching values passed
by const reference.
</p>

<p>
Matt Austern adds that this issue also exists for the <code>insert</code> and
<code>erase</code> members of the ordered and unordered associative containers.
</p>

<p><i>[
Berlin: Lots of controversey over how this should be solved. Lots of confusion
as to whether we're talking about self referencing iterators or references.
Needs a good survey as to the cases where this matters, for which
implementations, and how expensive it is to fix each case.
]</i></p>




<p id="res-526"><b>Proposed resolution:</b></p>


<p><b>Rationale:</b></p>
<p>
Recommend NAD.
</p>
<ul>
<li><code>vector::insert(iter, value)</code> is required to work because the standard
doesn't give permission for it not to work.</li>
<li><code>list::remove(value)</code> is required to work because the standard
doesn't give permission for it not to work.</li>
<li><code>vector::insert(iter, iter, iter)</code> is not required to work because
23.2.4 <a href="https://wg21.link/sequence.reqmts">[sequence.reqmts]</a>, p4 says so.</li>
<li><code>copy</code> has to work, except where 26.7.1 <a href="https://wg21.link/alg.copy">[alg.copy]</a> says
it doesn't have to work.  While a language lawyer can tear this wording apart,
it is felt that the wording is not prone to accidental interpretation.</li>
<li>The current working draft provide exceptions for the unordered associative
containers similar to the containers requirements which exempt the member
template insert functions from self referencing.</li>
</ul>





</body>
</html>
