{"id":399701,"date":"2024-06-29T14:49:33","date_gmt":"2024-06-29T14:49:33","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=399701"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=399701","title":{"rendered":"<span>How PVS-Studio prevents rash code changes, example N4<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/u3\/gu\/za\/u3guzacb7qda9odb8hw_wtowxaq.png\" alt=\"Blender, PVS-Studio, std::clamp\" data-src=\"https:\/\/habrastorage.org\/webt\/u3\/gu\/za\/u3guzacb7qda9odb8hw_wtowxaq.png\"\/><br \/>  If you regularly use a static code analyzer, you can save time on guessing why the new code doesn&#8217;t work as planned. Let&#8217;s look at another interesting error \u2014 the function broke during refactoring, and no one noticed that. No one \u2014 except for PVS-Studio that can automatically scan the project and email the report to us.<\/p>\n<p><a name=\"habracut\"><\/a>  <\/p>\n<p>It&#8217;s the fourth small note illustrating how quickly <a href=\"https:\/\/pvs-studio.com\/en\/pvs-studio\/\">PVS-Studio<\/a> finds errors in the new code. I thought of taking a break from it. But when I saw PVS-Studio&#8217;s report about <a href=\"https:\/\/github.com\/blender\/blender\">Blender<\/a> in my emails, I discarded this thought. Let me show you another error, simple and beautiful at the same time.<\/p>\n<p>  <\/p>\n<p>Once upon a time there was code that processed a vector of values. It prevented values from going beyond a certain range.<\/p>\n<p>  <\/p>\n<pre><code class=\"cpp\">#define CLAMP(a, b, c) \\   { \\     if ((a) &lt; (b)) { \\       (a) = (b); \\     } \\     else if ((a) > (c)) { \\       (a) = (c); \\     } \\   } \\   (void)0  template &lt;typename T> inline T clamp(const T &amp;a, const bT &amp;min_v, const bT &amp;max_v) {   T result = a;   for (int i = 0; i &lt; T::type_length; i++) {     CLAMP(result[i], min_v, max_v);   }   return result; }<\/code><\/pre>\n<p>  <\/p>\n<p>Everything was good. And then the developer decided to abandon the custom <em>CLAMP<\/em> macro and use the standard <em><a href=\"https:\/\/en.cppreference.com\/w\/cpp\/algorithm\/clamp\">std::clamp<\/a><\/em> function. And the <a href=\"https:\/\/github.com\/blender\/blender\/commit\/399168f3c13fadb41c9fbec8a1b5c56cb6609343\">commit<\/a> that supposed to make the code better looked like this:<\/p>\n<p>  <\/p>\n<pre><code class=\"cpp\">template &lt;typename T, int Size> inline vec_base&lt;T, Size>   clamp(const vec_base&lt;T, Size> &amp;a, const T &amp;min, const T &amp;max) {   vec_base&lt;T, Size> result = a;   for (int i = 0; i &lt; Size; i++) {     std::clamp(result[i], min, max);   }   return result; }<\/code><\/pre>\n<p>  <\/p>\n<p>It seems like the developer was in a hurry. Do you see the error? Maybe yes, maybe no. Anyway, the developer who wrote the code, didn&#8217;t notice that it was broken.<\/p>\n<p>  <\/p>\n<p>But the all-seeing PVS-Studio static analyzer warns us immediately:<\/p>\n<p>  <\/p>\n<p>[CWE-252] <a href=\"https:\/\/pvs-studio.com\/en\/docs\/warnings\/v530\/\">V530<\/a>: The return value of function &#8216;clamp&#8217; is required to be utilized. BLI_math_vector.hh 88<\/p>\n<p>  <\/p>\n<p>The point being \u2014 the <em><a href=\"https:\/\/en.cppreference.com\/w\/cpp\/algorithm\/clamp\">std::clamp<\/a><\/em> function doesn&#8217;t change the value of the element in the container:<\/p>\n<p>  <\/p>\n<pre><code class=\"cpp\">template &lt;class T> constexpr const T&amp; clamp( const T&amp; v, const T&amp; lo, const T&amp; hi );<\/code><\/pre>\n<p>  <\/p>\n<p>The <em>CLAMP<\/em> macro used to change the value, but the standard function did not. Now the code is broken and is waiting for someone to notice an error and look for its cause. With PVS-Studio, the developers could have found and fixed this error at the code writing stage. Using static analysis regularly, you can save your time and resources.<\/p>\n<p>  <\/p>\n<p>Note. By the way, there&#8217;s another incorrect use of <em>std::clamp<\/em> in the code.<\/p>\n<p>  <\/p>\n<p>The correct version of code: <\/p>\n<p>  <\/p>\n<pre><code class=\"cpp\">template &lt;typename T, int Size> inline vec_base&lt;T, Size> clamp(const vec_base&lt;T, Size> &amp;a, const T &amp;min, const T &amp;max) {   vec_base&lt;T, Size> result = a;   for (int i = 0; i &lt; Size; i++) {     result[i] = std::clamp(result[i], min, max);   }   return result; }<\/code><\/pre>\n<p>  <\/p>\n<p>Thank you for your time. And drop by to read about the <a href=\"https:\/\/pvs-studio.com\/en\/blog\/posts\/cpp\/0901\/\">top 10 bugs<\/a> found in C++ open-source projects in 2021.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/652381\/\"> https:\/\/habr.com\/ru\/articles\/652381\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/u3\/gu\/za\/u3guzacb7qda9odb8hw_wtowxaq.png\" alt=\"Blender, PVS-Studio, std::clamp\" data-src=\"https:\/\/habrastorage.org\/webt\/u3\/gu\/za\/u3guzacb7qda9odb8hw_wtowxaq.png\"\/><br \/>  If you regularly use a static code analyzer, you can save time on guessing why the new code doesn&#8217;t work as planned. Let&#8217;s look at another interesting error \u2014 the function broke during refactoring, and no one noticed that. No one \u2014 except for PVS-Studio that can automatically scan the project and email the report to us.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-399701","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/399701","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=399701"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/399701\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=399701"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=399701"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=399701"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}