<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 473: underspecified ctype calls</title>
<meta property="og:title" content="Issue 473: underspecified ctype calls">
<meta property="og:description" content="C++ library issue. Status: C++11">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue473.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#C++11">C++11</a> status.</em></p>
<h3 id="473"><a href="lwg-defects.html#473">473</a>. underspecified <code>ctype</code> calls</h3>
<p><b>Section:</b> 28.3.4.2.2 <a href="https://wg21.link/locale.ctype">[locale.ctype]</a> <b>Status:</b> <a href="lwg-active.html#C++11">C++11</a>
 <b>Submitter:</b> Martin Sebor <b>Opened:</b> 2004-07-01 <b>Last modified:</b> 2016-01-28</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View all issues with</b> <a href="lwg-status.html#C++11">C++11</a> status.</p>
<p><b>Discussion:</b></p>
<p>
Most <code>ctype</code> member functions come in two forms: one that operates
on a single character at a time and another form that operates
on a range of characters. Both forms are typically described by
a single Effects and&#47;or Returns clause.
</p>
<p>
The Returns clause of each of the single-character non-virtual forms
suggests that the function calls the corresponding single character
virtual function, and that the array form calls the corresponding
virtual array form. Neither of the two forms of each virtual member
function is required to be implemented in terms of the other.
</p>
<p>
There are three problems:
</p>
<p>
1. One is that while the standard does suggest that each non-virtual
member function calls the corresponding form of the virtual function,
it doesn't actually explicitly require it.
</p>
<p>
Implementations that cache results from some of the virtual member
functions for some or all values of their arguments might want to
call the array form from the non-array form the first time to fill
the cache and avoid any or most subsequent virtual calls. Programs
that rely on each form of the virtual function being called from
the corresponding non-virtual function will see unexpected behavior
when using such implementations.
</p>
<p>
2. The second problem is that either form of each of the virtual
functions can be overridden by a user-defined function in a derived
class to return a value that is different from the one produced by
the virtual function of the alternate form that has not been
overriden.
</p>
<p>
Thus, it might be possible for, say, <code>ctype::widen(c)</code> to return one
value, while for <code>ctype::widen(&amp;c, &amp;c + 1, &amp;wc)</code> to set
<code>wc</code> to another value. This is almost certainly not intended. Both
forms of every function should be required to return the same result
for the same character, otherwise the same program using an
implementation that calls one form of the functions will behave
differently than when using another implementation that calls the
other form of the function "under the hood."
</p>
<p>
3. The last problem is that the standard text fails to specify whether
one form of any of the virtual functions is permitted to be implemented
in terms of the other form or not, and if so, whether it is required
or permitted to call the overridden virtual function or not.
</p>
<p>
Thus, a program that overrides one of the virtual functions so that
it calls the other form which then calls the base member might end
up in an infinite loop if the called form of the base implementation
of the function in turn calls the other form.
</p>
<p>
Lillehammer: Part of this isn't a real problem. We already talk about
caching. 22.1.1&#47;6 But part is a real problem. <code>ctype</code> virtuals may call
each other, so users don't know which ones to override to avoid avoid
infinite loops.</p>

<p>This is a problem for all facet virtuals, not just <code>ctype</code> virtuals,
so we probably want a blanket statement in clause 22 for all
facets. The LWG is leaning toward a blanket prohibition, that a
facet's virtuals may never call each other. We might want to do that
in clause 27 too, for that matter. A review is necessary.  Bill will
provide wording.</p>

<p><i>[
2009-07 Frankfurt, Howard provided wording directed by consensus.
]</i></p>


<p><i>[
2009-10 Santa Cruz:
]</i></p>


<blockquote><p>
Move to Ready.
</p></blockquote>



<p id="res-473"><b>Proposed resolution:</b></p>
<p>
Add paragraph 3 to 28.3.4 <a href="https://wg21.link/locale.categories">[locale.categories]</a>:
</p>

<blockquote><p><ins>
-3- Within this clause it is unspecified if one virtual function calls another
virtual function.
</ins></p></blockquote>



<p><b>Rationale:</b></p>
<p>
We are explicitly not addressing bullet
item #2, thus giving implementors more latitude. Users will have to
override both virtual functions, not just one.
</p>




</body>
</html>
