Skip to content

Commit

Permalink
Deploying to gh-pages from @ ee3c651 🚀
Browse files Browse the repository at this point in the history
  • Loading branch information
loic-joly-sonarsource committed Mar 27, 2024
1 parent 51cf685 commit c64f018
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 49 deletions.
87 changes: 63 additions & 24 deletions rules/S5425/cfamily-description.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,60 +8,98 @@ <h2 id="_description">Description</h2>
<h2 id="_why_is_this_an_issue">Why is this an issue?</h2>
<div class="sectionbody">
<div class="paragraph">
<p><em>Forwarding references</em> are a special kind of references that both ignore and preserve the <em>value category</em> of a function argument, making it possible to forward it by means of <code>std::forward</code>.</p>
<p><em>Forwarding references</em> are a special kind of references that both ignore and preserve the <em>value category</em> of a function argument, making it possible to forward it by using <code>std::forward</code> or <code>std::forward_like</code>.</p>
</div>
<div class="paragraph">
<p>Any code using such a reference for any other purpose than forwarding is actually ignoring rvalue-ness and const-ness of the associated parameter.</p>
<p>Any code using such a reference for any purpose other than forwarding is actually ignoring the rvalue-ness and const-ness of the associated parameter.</p>
</div>
<div class="sect2">
<h3 id="_noncompliant_code_example">Noncompliant code example</h3>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cpp" data-lang="cpp">#include &lt;utility&gt;
#include &lt;string&gt;
#include &lt;iostream&gt;
<pre class="highlight"><code class="language-cpp" data-lang="cpp">class Registry {
std::vector&lt;std::string&gt; names;

template&lt;typename TP&gt; void f( TP&amp;&amp; arg ) {
std::string s(arg);
}
public:
template &lt;typename StringLike&gt;
void addName(StringLike&amp;&amp; arg) {
names.emplace_back(arg); // Not forwarded
}
};

int main() {
std::string s("test");
f(std::move(s));
std::cout&lt;&lt;"f:"&lt;&lt;s&lt;&lt;std::endl; // output is "f:test"
void example() {
Registry r;

return 0;
std::string name = "example";
r.addName(std::move(name));
std::cout &lt;&lt; "name:" &lt;&lt; name &lt;&lt; std::endl;
// output is "name:example"
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>In this example, the intent is to move the content of <code>name</code> into the vector, but instead a copy is made.</p>
</div>
</div>
<div class="sect2">
<h3 id="_compliant_solution">Compliant solution</h3>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cpp" data-lang="cpp">#include &lt;utility&gt;
#include &lt;string&gt;
#include &lt;iostream&gt;
<pre class="highlight"><code class="language-cpp" data-lang="cpp">class Registry {
std::vector&lt;std::string&gt; names;

template&lt;typename TP&gt; void f( TP&amp;&amp; arg ) {
std::string s(std::forward&lt;TP&gt;(arg));
}
public:
template &lt;typename StringLike&gt;
void addName(StringLike&amp;&amp; arg) {
names.emplace_back(std::forward&lt;StringLike&gt;(arg));
}
};

int main() {
std::string s("test");
f(std::move(s));
std::cout&lt;&lt;"f:"&lt;&lt;s&lt;&lt;std::endl; // output is "f:"
void example() {
Registry r;

return 0;
std::string name = "example";
r.addName(std::move(name));
std::cout &lt;&lt; "name:" &lt;&lt; name &lt;&lt; std::endl;
// output can be anything: name has been moved-from
}</code></pre>
</div>
</div>
<div class="paragraph">
<p><code>std::forward_like</code> is available since C&#43;&#43;23 and is useful when you want to forward a subobject of a forwarding reference.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cpp" data-lang="cpp">class Registry {
// ...
template &lt;typename PairOfStrings&gt;
void addNames(PairOfStrings&amp;&amp; arg) {
addName(std::forward_like&lt;PairOfStrings&gt;(arg.second)); // We don't care about arg.first
}
};</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_resources">Resources</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_documentation">Documentation</h3>
<div class="ulist">
<ul>
<li>
<p>C&#43;&#43; reference - <a href="https://en.cppreference.com/w/cpp/utility/forward"><code>std::forward</code></a></p>
</li>
<li>
<p>C&#43;&#43; reference - <a href="https://en.cppreference.com/w/cpp/utility/forward_like"><code>std::forward_like</code></a></p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_external_coding_guidelines">External coding guidelines</h3>
<div class="ulist">
<ul>
<li>
Expand All @@ -72,6 +110,7 @@ <h2 id="_resources">Resources</h2>
<hr>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_implementation_specification">Implementation Specification</h2>
<div class="sectionbody">
Expand Down
87 changes: 63 additions & 24 deletions rules/S5425/default-description.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,60 +8,98 @@ <h2 id="_description">Description</h2>
<h2 id="_why_is_this_an_issue">Why is this an issue?</h2>
<div class="sectionbody">
<div class="paragraph">
<p><em>Forwarding references</em> are a special kind of references that both ignore and preserve the <em>value category</em> of a function argument, making it possible to forward it by means of <code>std::forward</code>.</p>
<p><em>Forwarding references</em> are a special kind of references that both ignore and preserve the <em>value category</em> of a function argument, making it possible to forward it by using <code>std::forward</code> or <code>std::forward_like</code>.</p>
</div>
<div class="paragraph">
<p>Any code using such a reference for any other purpose than forwarding is actually ignoring rvalue-ness and const-ness of the associated parameter.</p>
<p>Any code using such a reference for any purpose other than forwarding is actually ignoring the rvalue-ness and const-ness of the associated parameter.</p>
</div>
<div class="sect2">
<h3 id="_noncompliant_code_example">Noncompliant code example</h3>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cpp" data-lang="cpp">#include &lt;utility&gt;
#include &lt;string&gt;
#include &lt;iostream&gt;
<pre class="highlight"><code class="language-cpp" data-lang="cpp">class Registry {
std::vector&lt;std::string&gt; names;

template&lt;typename TP&gt; void f( TP&amp;&amp; arg ) {
std::string s(arg);
}
public:
template &lt;typename StringLike&gt;
void addName(StringLike&amp;&amp; arg) {
names.emplace_back(arg); // Not forwarded
}
};

int main() {
std::string s("test");
f(std::move(s));
std::cout&lt;&lt;"f:"&lt;&lt;s&lt;&lt;std::endl; // output is "f:test"
void example() {
Registry r;

return 0;
std::string name = "example";
r.addName(std::move(name));
std::cout &lt;&lt; "name:" &lt;&lt; name &lt;&lt; std::endl;
// output is "name:example"
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>In this example, the intent is to move the content of <code>name</code> into the vector, but instead a copy is made.</p>
</div>
</div>
<div class="sect2">
<h3 id="_compliant_solution">Compliant solution</h3>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cpp" data-lang="cpp">#include &lt;utility&gt;
#include &lt;string&gt;
#include &lt;iostream&gt;
<pre class="highlight"><code class="language-cpp" data-lang="cpp">class Registry {
std::vector&lt;std::string&gt; names;

template&lt;typename TP&gt; void f( TP&amp;&amp; arg ) {
std::string s(std::forward&lt;TP&gt;(arg));
}
public:
template &lt;typename StringLike&gt;
void addName(StringLike&amp;&amp; arg) {
names.emplace_back(std::forward&lt;StringLike&gt;(arg));
}
};

int main() {
std::string s("test");
f(std::move(s));
std::cout&lt;&lt;"f:"&lt;&lt;s&lt;&lt;std::endl; // output is "f:"
void example() {
Registry r;

return 0;
std::string name = "example";
r.addName(std::move(name));
std::cout &lt;&lt; "name:" &lt;&lt; name &lt;&lt; std::endl;
// output can be anything: name has been moved-from
}</code></pre>
</div>
</div>
<div class="paragraph">
<p><code>std::forward_like</code> is available since C&#43;&#43;23 and is useful when you want to forward a subobject of a forwarding reference.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cpp" data-lang="cpp">class Registry {
// ...
template &lt;typename PairOfStrings&gt;
void addNames(PairOfStrings&amp;&amp; arg) {
addName(std::forward_like&lt;PairOfStrings&gt;(arg.second)); // We don't care about arg.first
}
};</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_resources">Resources</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_documentation">Documentation</h3>
<div class="ulist">
<ul>
<li>
<p>C&#43;&#43; reference - <a href="https://en.cppreference.com/w/cpp/utility/forward"><code>std::forward</code></a></p>
</li>
<li>
<p>C&#43;&#43; reference - <a href="https://en.cppreference.com/w/cpp/utility/forward_like"><code>std::forward_like</code></a></p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_external_coding_guidelines">External coding guidelines</h3>
<div class="ulist">
<ul>
<li>
Expand All @@ -72,6 +110,7 @@ <h2 id="_resources">Resources</h2>
<hr>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_implementation_specification">Implementation Specification</h2>
<div class="sectionbody">
Expand Down
2 changes: 1 addition & 1 deletion rules/rule-index.json

Large diffs are not rendered by default.

0 comments on commit c64f018

Please sign in to comment.