<!DOCTYPE html>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<html>
<style type="text/css">
  ins, ins * { text-decoration:none; font-weight:bold; background-color:#A0FFA0 }
  del, del * { text-decoration:line-through; background-color:#FFA0A0 }
  #hidedel:checked ~ * del, #hidedel:checked ~ * del * { display:none; visibility:hidden }

blockquote {
  padding: .5em;
  border: .5em;
  border-color: silver;
  border-left-style: solid;
}

blockquote.std { color: #000000; background-color: #F1F1F1;
  border: 1px solid #D1D1D1;
  padding-left: 0.5em; padding-right: 0.5em; }
blockquote.stdins { text-decoration: underline;
  color: #000000; background-color: #C8FFC8;
  border: 1px solid #B3EBB3; padding: 0.5em; }
blockquote.stddel { text-decoration: line-through;
  color: #000000; background-color: #FFEBFF;
  border: 1px solid #ECD7EC;
  padding-left: 0.5em; padding-right: 0.5em; }

p.grammarlhs { margin-bottom: 0 }
p.grammarrhs { margin-left:8em; margin-top:0; margin-bottom:0; text-indent:-4em }

div.wrapper {
    max-width: 60em;
    margin: auto;
}

a { text-decoration: none; }

a.hidden_link {
    text-decoration: none;
    color: inherit;
}

li {
    margin-top: 0.0em;
    margin-bottom: 0.0em;
}

h1 { line-height: 1; }
h2 { line-height: 1; }
h3 { line-height: 1; }
h4 { line-height: 1; }

:target { background-color: #C9FBC9; }
:target .codeblock { background-color: #C9FBC9; }
:target ul { background-color: #C9FBC9; }

.abbr_ref { float: right; }

.folded_abbr_ref { float: right; }
:target .folded_abbr_ref { display: none; }

:target .unfolded_abbr_ref { float: right; display: inherit; }
.unfolded_abbr_ref { display: none; }

.secnum { display: inline-block; min-width: 35pt; }
.annexnum { display: block; }

div.sourceLinkParent {
    float: right;
}

a.sourceLink {
    position: absolute;
    opacity: 0;
    margin-left: 10pt;
}

a.sourceLink:hover {
    opacity: 1;
}

div.marginalizedparent {
    position: relative;
    left: -5em;
}

div.footnoteNumberParent {
    position: relative;
    left: -4.7em;
}

a.marginalized {
    position: absolute;
    font-size: 75%;
    text-align: right;
    width: 5em;
}

a.enumerated_item_num {
    position: relative;
    left: -3.5em;
    display: inline-block;
    margin-right: -3em;
    text-align: right;
    width: 3em;
}

div.para { margin-bottom: 0.6em; margin-top: 0.6em; text-align: justify; }
div.section { text-align: justify; }
div.sentence { display: inline; }

span.indexparent {
    display: inline;
    position: relative;
    float: right;
    right: -1em;
}

a.index {
    position: absolute;
    display: none;
}

a.index:before { content: "Ã¢Å¸Âµ"; }
    /* this way the content is not selectable */

a.index:target {
    display: inline;
}

.indexitems {
    margin-left: 2em;
    text-indent: -2em;
}

div.itemdescr {
    margin-left: 3em;
}

.bnf {
    font-family: serif;
    margin-left: 40pt;
    margin-top: 0.5em;
    margin-bottom: 0.5em;
}

.ncbnf {
    font-family: serif;
    margin-top: 0.5em;
    margin-bottom: 0.5em;
    margin-left: 40pt;
}

.bnftab {
    font-family: serif;
    font-style: italic;
    margin-left: 40pt;
    margin-top: 0.5em;
    margin-bottom: 0.5em;
}

.ncsimplebnf {
    font-family: serif;
    font-style: italic;
    margin-top: 0.5em;
    margin-bottom: 0.5em;
    margin-left: 40pt;
}

.ncbnftab {
    font-family: serif;
    font-style: italic;
    margin-top: 0.5em;
    margin-bottom: 0.5em;
    margin-left: 40pt;
}

.bnfkeywordtab {
    margin-top: 0.5em;
    margin-bottom: 0.5em;
    margin-left: 40pt;
}

span.textnormal {
    font-style: normal;
    font-family: serif;
    white-space: normal;
    display: inline-block;
}

span.descr { font-style: normal; font-family: serif; }
span.grammarterm { font-style: italic; }
span.term { font-style: italic; }
span.terminal { font-family: monospace; font-style: normal; }
span.nonterminal { font-style: italic; }
span.tcode { font-family: monospace; font-style: normal; }
span.textbf { font-weight: bold; }
span.textsc { font-variant: small-caps; }
a.nontermdef { font-style: italic; font-family: serif; }
span.emph { font-style: italic; }
span.techterm { font-style: italic; }
span.mathit { font-style: italic; }
span.mathsf { font-family: sans-serif; }
span.mathrm { font-family: serif; font-style: normal; }
span.textrm { font-family: serif; }
span.textsl { font-style: italic; }
span.mathtt { font-family: monospace; font-style: normal; }
span.mbox { font-family: serif; font-style: normal; }
span.ungap { display: inline-block; width: 2pt; }
span.textit { font-style: italic; }
span.texttt { font-family: monospace; }
span.tcode_in_codeblock { font-family: monospace; font-style: normal; }

span.phantom { color: white; }
span.math { }

span.mathblock {
    display: block;
    margin-left: auto;
    margin-right: auto;
    margin-top: 1.2em;
    margin-bottom: 1.2em;
    text-align: center;
}

span.mathalpha {
    font-style: italic;
}

span.synopsis {
    font-weight: bold;
    margin-top: 0.5em;
    display: block;
}

span.definition {
    font-weight: bold;
    display: block;
}

span.keyword {
  color: #00607c;
  font-style: normal;
}

.codeblock {
  font-family: Courier New;
  margin-left: 1.2em;
  line-height: 140%;
  font-size: 10pt;
  white-space: pre;
  display: block;
  margin-top: 3pt;
  margin-bottom: 3pt;
  overflow: auto;
  margin-right: -15mm;
}

code {
    font-family: monospace;
    font-style: normal;
}

code.itemdecl {
    margin-top: 2ex;
    white-space: pre;
    display: block;
}

code.itemdeclcode {
    white-space: pre;
    font-family: Courier New;
    font-size: 10pt;
    display: block;
    overflow: auto;
    margin-right: -15mm;
}

.comment {
    font-style: italic;
    font-family: serif;
}

span.textsuperscript {
    vertical-align: super;
    font-size: smaller;
    line-height: 0;
}

.footnotenum { vertical-align: super; font-size: smaller; line-height: 0; }

.footnote {
    font-size: small;
    margin-left: 2em;
    margin-right: 2em;
    margin-top: 0.6em;
    margin-bottom: 0.6em;
}

div.minipage {
    display: inline-block;
    margin-right: 3em;
}

div.numberedTable {
    text-align: center;
    margin: 2em;
}

div.figure {
    text-align: center;
    margin: 2em;
}

table {
    border: 1px solid black;
    border-collapse: collapse;
    margin-left: auto;
    margin-right: auto;
    margin-top: 0.8em;
    text-align: left;
    hyphens: none; /* otherwise some columns get very narrow, e.g. [tab:hash] */
}

td, th {
    padding-left: 1em;
    padding-right: 1em;
    vertical-align: top;
}

td.left {
    text-align: left;
}

td.right {
    text-align: right;
}

td.center {
    text-align: center;
}

td.justify {
    text-align: justify;
}

td.border {
    border-left: 1px solid black;
}

tr.rowsep, td.cline {
    border-top: 1px solid black;
}

tr.capsep {
    border-top: 3px solid black;
    border-top-style: double;
}

th {
    border-bottom: 1px solid black;
}

span.centry {
    font-weight: bold;
}

div.table {
    display: block;
    margin-left: auto;
    margin-right: auto;
    text-align: center;
    width: 90%;
}

span.indented {
    display: block;
    margin-left: 2em;
    margin-bottom: 1em;
    margin-top: 1em;
}
</style>

<title>P2937R0: Freestanding: Remove <code>strtok</code></title>
<body>
<h1>Freestanding: Remove <code>strtok</code></h1>
Document number: P2937R0<br/>
Date: 2023-07-02<br/>
Reply-to:<br/>
&emsp;&emsp;Ben Craig &lt;ben dot craig at gmail dot com&gt;<br/>
Audience: Library Evolution Working Group

<h1>Changes from previous revisions</h1>
First revision!

<h1>Introduction</h1>
Remove <code>strtok</code> from C++ freestanding, because C2X freestanding no longer includes <code>strtok</code> in C freestanding.

<h1>History and Rationale</h1>
<p>
<code>strtok</code> was added to C++ freestanding as part of <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2338r4.html">P2338R4 (Freestanding Library: Character primitives and the C library)</a>.
P2338R0 and P2338R1 did not include <code>strtok</code>, as <code>strtok</code> uses global storage that is difficult to synchronize in freestanding environments.
(In practice, freestanding environments aren't guaranteed to have storage that is local to a thread, mutexes, or atomics larger than <code>atomic_flag</code>).
In P2338R2 only added <code>strtok</code> because C2X added <code>strtok</code> to C freestanding.
</p><p>
In C2X CD2, C removed <code>strtok</code> from C freestanding.
Now that <code>strtok</code> doesn't aid in C compatibility, C++ can now remove <code>strtok</code> from C++ freestanding.
</p><p>
Even though <code>strtok</code> is not required to avoid data races, good implementations do so.
Freestanding shouldn't encourage implementations to provide poor implementations.
</p>

<h1>Wording</h1>
This paper’s wording is based on the working draft, <a href="https://wg21.link/N4950">[N4950]</a>,
plus the anticipated inclusion of merging <a href="https://wg21.link/P2338R4">[P2338R4] (Freestanding Library: Character primitives and the C library)</a>.

<h2>Change in <a href="https://wg21.link/version.syn#2">[version.syn]</a></h2>
<p>
Please update the value of the <code>__cpp_lib_freestanding_cstring</code> feature test macro.
</p>
<blockquote class="std">
<pre class="codeblock"><span class="keyword">#define</span> __cpp_lib_freestanding_cstring      <i><del>old-val</del><ins>new-val</ins></i> <span class="comment">// freestanding, also in &lt;cstring&gt;</span></pre>
</blockquote>

<h2>Change in <a href="https://eel.is/c++draft/cstring.syn">[cstring.syn]</a></h2>
Modify <a href="https://eel.is/c++draft/cstring.syn">[cstring.syn]</a>.

<blockquote class="std">
<span class="codeblock">  <span class="keyword">char</span>* strstr(<span class="keyword">char</span>* s1, <span class="keyword">const</span> <span class="keyword">char</span>* s2);                       <span class="comment">// freestanding, see <a href="https://eel.is/c++draft/library.c">[library.c]</a></span>
  <span class="keyword">char</span>* strtok(<span class="keyword">char</span>* s1, <span class="keyword">const</span> <span class="keyword">char</span>* s2);<del>                       <span class="comment">// freestanding</span></del>
  <span class="keyword">void</span>* memset(<span class="keyword">void</span>* s, <span class="keyword">int</span> c, size_t n);                       <span class="comment">// freestanding</span>
</span>
</blockquote>

<h1>References</h1>

[N4950] Thomas Köppe. 2023-05-10. Working Draft, Standard for Programming Language C++.<br/>
&emsp;&emsp;https://wg21.link/N4950<br/>
[P2338R4] Ben Craig. 2023-02-09. Freestanding Library: Character primitives and the C library<br/>
&emsp;&emsp;https://wg21.link/P2338R4<br/>

</body>
</html>
