{"id":395,"date":"2018-02-19T21:43:01","date_gmt":"2018-02-19T21:43:01","guid":{"rendered":"http:\/\/cppdepend.com\/blog\/?p=395"},"modified":"2018-02-19T21:43:01","modified_gmt":"2018-02-19T21:43:01","slug":"easy-steps-to-modernize-your-c-code","status":"publish","type":"post","link":"https:\/\/cppdepend.com\/blog\/easy-steps-to-modernize-your-c-code\/","title":{"rendered":"Easy steps to modernize your C++ code."},"content":{"rendered":"<p>Recently the C++ community\u00a0 promotes the use of\u00a0the new standards to modernize the existing code base.\u00a0 However even before the release of the C++11 standard\u00a0some known\u00a0C++ experts\u00a0like Andrei Alexandrescu, Scott Meyers and Herb Sutter promotes the uses of the generic programming and they qualify it as Modern C++ Design.\u00a0Here\u2019s what say Andrei Alexandrescu about the Modern C++ design:<\/p>\n<blockquote><p>Modern C++ Design defines and systematically uses\u00a0<i>generic components<\/i>\u00a0&#8211; highly flexible design artifacts that are mixable and matchable to obtain rich behaviors with a small, orthogonal body of code.<\/p><\/blockquote>\n<p>Three\u00a0assertions are interesting in his point of view:<!--more--><\/p>\n<ul>\n<li>Modern C++ Design defines and\u00a0<strong>systematically uses\u00a0<\/strong><strong>generic components<\/strong>.<\/li>\n<li>Highly\u00a0<strong>flexible<\/strong>\u00a0design.<\/li>\n<li>Obtain rich behaviors with a\u00a0<strong>small, orthogonal<\/strong>\u00a0body of code.<\/li>\n<\/ul>\n<p>Modernize your C++ code it&#8217;s not only about using the new standards but we can also use some generics programming\u00a0 best practices to improve our code base. Let&#8217;s first discover some easy steps to manually modernize our code base and in the second section we will explore how to automatically modernize it.<\/p>\n<p><strong>II &#8211;\u00a0Modernize manually your\u00a0source code<\/strong><\/p>\n<p>Let&#8217;s take as example an algorithm and try to modernize it. Algorithms are used for calculation, data processing, and automated reasoning. Programming them\u00a0is not always an easy task and it depends on their complexity.\u00a0In C++ many efforts was done to simplify their implementation and to make them more powerful.<\/p>\n<p>Let&#8217;s\u00a0try to modernize this implementation of\u00a0\u00a0the quick sort algorithm:<span id=\"more-598\"><\/span><\/p>\n<pre class=\"prettyprint prettyprinted\"><code><span class=\"com\">\/\/ The partition function\r\n<\/span><span class=\"kwd\">int<\/span><span class=\"pln\"> partition<\/span><span class=\"pun\">(<\/span><span class=\"kwd\">int<\/span><span class=\"pun\">*<\/span><span class=\"pln\"> input<\/span><span class=\"pun\">,<\/span><span class=\"kwd\">int<\/span><span class=\"pln\"> p<\/span><span class=\"pun\">,<\/span><span class=\"kwd\">int<\/span><span class=\"pln\"> r<\/span><span class=\"pun\">)<\/span><span class=\"pun\">{\r\n<\/span><span class=\"kwd\">        int<\/span><span class=\"pln\"> pivot <\/span><span class=\"pun\">=<\/span><span class=\"pln\"> input<\/span><span class=\"pun\">[<\/span><span class=\"pln\">r<\/span><span class=\"pun\">];\r\n<\/span><span class=\"kwd\">        while<\/span><span class=\"pun\">(<\/span><span class=\"pln\"> p <\/span><span class=\"pun\">&lt;<\/span><span class=\"pln\"> r <\/span><span class=\"pun\">)<\/span><span class=\"pun\">{\r\n<\/span><span class=\"kwd\">                 while<\/span><span class=\"pun\">(<\/span><span class=\"pln\"> input<\/span><span class=\"pun\">[<\/span><span class=\"pln\">p<\/span><span class=\"pun\">]<\/span><span class=\"pun\">&lt;<\/span><span class=\"pln\"> pivot <\/span><span class=\"pun\">)<\/span><span class=\"pln\">\r\n                     p<\/span><span class=\"pun\">++;\r\n<\/span><span class=\"kwd\">                 while<\/span><span class=\"pun\">(<\/span><span class=\"pln\"> input<\/span><span class=\"pun\">[<\/span><span class=\"pln\">r<\/span><span class=\"pun\">]<\/span><span class=\"pun\">&gt;<\/span><span class=\"pln\"> pivot <\/span><span class=\"pun\">)<\/span><span class=\"pln\">\r\n                    r<\/span><span class=\"pun\">--;\r\n<\/span><span class=\"kwd\">                if<\/span><span class=\"pun\">(<\/span><span class=\"pln\"> input<\/span><span class=\"pun\">[<\/span><span class=\"pln\">p<\/span><span class=\"pun\">]<\/span><span class=\"pun\">==<\/span><span class=\"pln\"> input<\/span><span class=\"pun\">[<\/span><span class=\"pln\">r<\/span><span class=\"pun\">]<\/span><span class=\"pun\">)<\/span><span class=\"pln\">\r\n                    p<\/span><span class=\"pun\">++;\r\n<\/span><span class=\"kwd\">                else<\/span><span class=\"kwd\">if<\/span><span class=\"pun\">(<\/span><span class=\"pln\"> p <\/span><span class=\"pun\">&lt;<\/span><span class=\"pln\"> r <\/span><span class=\"pun\">)<\/span><span class=\"pun\">{\r\n<\/span><span class=\"kwd\">                     int<\/span><span class=\"pln\"> tmp <\/span><span class=\"pun\">=<\/span><span class=\"pln\"> input<\/span><span class=\"pun\">[<\/span><span class=\"pln\">p<\/span><span class=\"pun\">];<\/span><span class=\"pln\">\r\n                     input<\/span><span class=\"pun\">[<\/span><span class=\"pln\">p<\/span><span class=\"pun\">]<\/span><span class=\"pun\">=<\/span><span class=\"pln\"> input<\/span><span class=\"pun\">[<\/span><span class=\"pln\">r<\/span><span class=\"pun\">];<\/span><span class=\"pln\">\r\n                     input<\/span><span class=\"pun\">[<\/span><span class=\"pln\">r<\/span><span class=\"pun\">]<\/span><span class=\"pun\">=<\/span><span class=\"pln\"> tmp<\/span><span class=\"pun\">;\r\n<\/span><span class=\"pun\">                }\r\n<\/span><span class=\"pun\">        }\r\n<\/span><span class=\"kwd\">         return<\/span><span class=\"pln\"> r<\/span><span class=\"pun\">;\r\n<\/span><span class=\"pun\">}\r\n<\/span><span class=\"com\">\/\/ The quicksort recursive function\r\n<\/span><span class=\"kwd\">void<\/span><span class=\"pln\"> quicksort<\/span><span class=\"pun\">(<\/span><span class=\"kwd\">int<\/span><span class=\"pun\">*<\/span><span class=\"pln\"> input<\/span><span class=\"pun\">,<\/span><span class=\"kwd\">int<\/span><span class=\"pln\"> p<\/span><span class=\"pun\">,<\/span><span class=\"kwd\">int<\/span><span class=\"pln\"> r<\/span><span class=\"pun\">)<\/span><span class=\"pun\">{\r\n<\/span><span class=\"kwd\">        if<\/span><span class=\"pun\">(<\/span><span class=\"pln\"> p <\/span><span class=\"pun\">&lt;<\/span><span class=\"pln\"> r <\/span><span class=\"pun\">)<\/span><span class=\"pun\">{\r\n<\/span><span class=\"kwd\">              int<\/span><span class=\"pln\"> j <\/span><span class=\"pun\">=<\/span><span class=\"pln\"> partition<\/span><span class=\"pun\">(<\/span><span class=\"pln\">input<\/span><span class=\"pun\">,<\/span><span class=\"pln\"> p<\/span><span class=\"pun\">,<\/span><span class=\"pln\"> r<\/span><span class=\"pun\">);<\/span><span class=\"pln\">        \r\n              quicksort<\/span><span class=\"pun\">(<\/span><span class=\"pln\">input<\/span><span class=\"pun\">,<\/span><span class=\"pln\"> p<\/span><span class=\"pun\">,<\/span><span class=\"pln\"> j<\/span><span class=\"pun\">-<\/span><span class=\"lit\">1<\/span><span class=\"pun\">);<\/span><span class=\"pln\">\r\n              quicksort<\/span><span class=\"pun\">(<\/span><span class=\"pln\">input<\/span><span class=\"pun\">,<\/span><span class=\"pln\"> j<\/span><span class=\"pun\">+<\/span><span class=\"lit\">1<\/span><span class=\"pun\">,<\/span><span class=\"pln\"> r<\/span><span class=\"pun\">);\r\n<\/span><span class=\"pun\">        }\r\n<\/span><span class=\"pun\">}<\/span><\/code><\/pre>\n<p>After all, here are some\u00a0common traits of algorithms:<\/p>\n<ul>\n<li>Using containers of \u00a0an element kind and Iterating over\u00a0them.<\/li>\n<li>Comparison between elements.<\/li>\n<li>And of course some \u00a0treatments over elements.<\/li>\n<\/ul>\n<p>In our implementation the container is a raw array of int, we iterate thought increment and decrement. We compare using \u201c&lt;\u201d and \u201c&gt;\u201d, and we have some treatments like swapping data.<\/p>\n<p>Let\u2019s try to improve each one of these traits:<\/p>\n<p><strong>Step1: Replace containers by iterators<\/strong><\/p>\n<p>Using not generic containers will force us to use a specific element kind.\u00a0To apply the same algorithm to other types, we have to copy\/paste the code. The generic containers resolve this issue, and permit to use any element kind, for example for our quick sort algorithm, we can use std::vector&lt;T&gt; as container instead of a raw array.<\/p>\n<p>A raw array or an std::vector \u00a0is just one possibility between many others to represent a set of elements, we can also apply the same algorithm to\u00a0a linked list, a queue or whatever other container. For this needs the iterator is the best choice to abstract the container used.<\/p>\n<p>An\u00a0iterator\u00a0is any object that, pointing to some element in a range of elements , has the ability to iterate through the elements of that range using a set of operators (with at least the increment (++) and dereference (*) operators).\u00a0Iterators are classified into five categories depending on the functionality they implement: Input, Output, Forward, Bidirectional and random access.<\/p>\n<p>In our algorithm\u00a0we have to specify which kind of iterator to use. For that we have to detect \u00a0which iterations are used.\u00a0For the quick sort algo the \u00a0increment and \u00a0decrement iterations are applied. Therefore, a bidirectional iterator is needed.\u00a0Using iterators we can \u00a0define the method like this:<\/p>\n<pre class=\"de1\"><span class=\"kw2\">template<\/span><span class=\"sy1\">&lt;<\/span> <span class=\"kw2\">typename<\/span> BidirectionalIterator <span class=\"sy1\">&gt;<\/span>\r\n<span class=\"kw4\">void<\/span> quick_sort<span class=\"br0\">(<\/span> BidirectionalIterator first, BidirectionalIterator last <span class=\"br0\">)<\/span><\/pre>\n<p><strong>Step2: Make the comparator generic if possible<\/strong><\/p>\n<p>For some algorithms, the elements treated are not only numbers, they could be string or a class. In this case make the comparator generic will permit us to have a more generic algorithm.<\/p>\n<p>The quick sort algorithm could also be applied to a list of strings, Therefore it\u2019s better to have a generic comparator.<\/p>\n<p>After using a\u00a0generic comparator, the definition could be modified like this:<\/p>\n<pre class=\"de1\"><span class=\"kw2\">template<\/span><span class=\"sy1\">&lt;<\/span> <span class=\"kw2\">typename<\/span> BidirectionalIterator, <span class=\"kw2\">typename<\/span> Compare <span class=\"sy1\">&gt;<\/span>\r\n<span class=\"kw4\">void<\/span> quick_sort<span class=\"br0\">(<\/span> BidirectionalIterator first, BidirectionalIterator last, Compare cmp <span class=\"br0\">)<\/span><\/pre>\n<p><strong>Step3: Replace treatments by standard ones<\/strong><\/p>\n<p>Most algorithms use recurrent treatments like min, max and swap. for these operations it\u2019s preferable to not reinvent the wheel, and uses the standard implementation existing in the &lt;algorithm&gt; header.<\/p>\n<p>In our case we can use the swap method from the STL than creating our specific method.<\/p>\n<pre class=\"de1\">std<span class=\"sy4\">::<\/span><span class=\"me2\">iter_swap<\/span><span class=\"br0\">(<\/span> pivot, left <span class=\"br0\">)<\/span><span class=\"sy4\">;<\/span><\/pre>\n<p>And here\u2019s the modified result after these three steps:<\/p>\n<pre class=\"de1\"><span class=\"co2\">#include &lt;functional&gt;<\/span>\r\n<span class=\"co2\">#include &lt;algorithm&gt;<\/span>\r\n<span class=\"co2\">#include &lt;iterator&gt;<\/span>\r\n \r\n<span class=\"kw2\">template<\/span><span class=\"sy1\">&lt;<\/span> <span class=\"kw2\">typename<\/span> BidirectionalIterator, <span class=\"kw2\">typename<\/span> Compare <span class=\"sy1\">&gt;<\/span>\r\n<span class=\"kw4\">void<\/span> quick_sort<span class=\"br0\">(<\/span> BidirectionalIterator first, BidirectionalIterator last, Compare cmp <span class=\"br0\">)<\/span> <span class=\"br0\">{<\/span>\r\n    <span class=\"kw1\">if<\/span><span class=\"br0\">(<\/span> first <span class=\"sy3\">!<\/span><span class=\"sy1\">=<\/span> last <span class=\"br0\">)<\/span> <span class=\"br0\">{<\/span>\r\n        BidirectionalIterator left  <span class=\"sy1\">=<\/span> first<span class=\"sy4\">;<\/span>\r\n        BidirectionalIterator right <span class=\"sy1\">=<\/span> last<span class=\"sy4\">;<\/span>\r\n        BidirectionalIterator pivot <span class=\"sy1\">=<\/span> left<span class=\"sy2\">++<\/span><span class=\"sy4\">;<\/span>\r\n \r\n        <span class=\"kw1\">while<\/span><span class=\"br0\">(<\/span> left <span class=\"sy3\">!<\/span><span class=\"sy1\">=<\/span> right <span class=\"br0\">)<\/span> <span class=\"br0\">{<\/span>\r\n            <span class=\"kw1\">if<\/span><span class=\"br0\">(<\/span> cmp<span class=\"br0\">(<\/span> <span class=\"sy2\">*<\/span>left, <span class=\"sy2\">*<\/span>pivot <span class=\"br0\">)<\/span> <span class=\"br0\">)<\/span> <span class=\"br0\">{<\/span>\r\n                <span class=\"sy2\">++<\/span>left<span class=\"sy4\">;<\/span>\r\n            <span class=\"br0\">}<\/span> <span class=\"kw1\">else<\/span> <span class=\"br0\">{<\/span>\r\n                <span class=\"kw1\">while<\/span><span class=\"br0\">(<\/span> <span class=\"br0\">(<\/span>left <span class=\"sy3\">!<\/span><span class=\"sy1\">=<\/span> right<span class=\"br0\">)<\/span> <span class=\"sy3\">&amp;&amp;<\/span> cmp<span class=\"br0\">(<\/span> <span class=\"sy2\">*<\/span>pivot, <span class=\"sy2\">*<\/span>right <span class=\"br0\">)<\/span> <span class=\"br0\">)<\/span>\r\n                    <span class=\"sy2\">--<\/span>right<span class=\"sy4\">;<\/span>\r\n                std<span class=\"sy4\">::<\/span><span class=\"me2\">iter_swap<\/span><span class=\"br0\">(<\/span> left, right <span class=\"br0\">)<\/span><span class=\"sy4\">;<\/span>\r\n            <span class=\"br0\">}<\/span>\r\n        <span class=\"br0\">}<\/span>\r\n \r\n        <span class=\"sy2\">--<\/span>left<span class=\"sy4\">;<\/span>\r\n        std<span class=\"sy4\">::<\/span><span class=\"me2\">iter_swap<\/span><span class=\"br0\">(<\/span> pivot, left <span class=\"br0\">)<\/span><span class=\"sy4\">;<\/span>\r\n \r\n        quick_sort<span class=\"br0\">(<\/span> first, left, cmp <span class=\"br0\">)<\/span><span class=\"sy4\">;<\/span>\r\n        quick_sort<span class=\"br0\">(<\/span> right, last, cmp <span class=\"br0\">)<\/span><span class=\"sy4\">;<\/span>\r\n    <span class=\"br0\">}<\/span>\r\n<span class=\"br0\">}<\/span>\r\n \r\n<span class=\"kw2\">template<\/span><span class=\"sy1\">&lt;<\/span> <span class=\"kw2\">typename<\/span> BidirectionalIterator <span class=\"sy1\">&gt;<\/span>\r\n    <span class=\"kw2\">inline<\/span> <span class=\"kw4\">void<\/span> quick_sort<span class=\"br0\">(<\/span> BidirectionalIterator first, BidirectionalIterator last <span class=\"br0\">)<\/span> <span class=\"br0\">{<\/span>\r\n        quick_sort<span class=\"br0\">(<\/span> first, last,\r\n                std<span class=\"sy4\">::<\/span><span class=\"me2\">less_equal<\/span><span class=\"sy1\">&lt;<\/span> <span class=\"kw2\">typename<\/span> std<span class=\"sy4\">::<\/span><span class=\"me2\">iterator_traits<\/span><span class=\"sy1\">&lt;<\/span> BidirectionalIterator <span class=\"sy1\">&gt;<\/span><span class=\"sy4\">::<\/span><span class=\"me2\">value_type<\/span> <span class=\"sy1\">&gt;<\/span><span class=\"br0\">(<\/span><span class=\"br0\">)<\/span>\r\n                <span class=\"br0\">)<\/span><span class=\"sy4\">;<\/span>\r\n    <span class=\"br0\">}<\/span><\/pre>\n<p>This implementation has the following advantages:<\/p>\n<ul>\n<li>Could be applied to many element kind.<\/li>\n<li>The container could be vector, set, list or whatever container with a biderectional iterator.<\/li>\n<li>It uses a well optimized and tested standard functions.<\/li>\n<\/ul>\n<p><strong>II- Automatic modernization<\/strong><\/p>\n<p>It\u2019s interesting to detect automatically places where we can use some C++11\/C++14\/C++17 features and if possible change the code automatically. For such needs\u00a0<a href=\"http:\/\/clang.llvm.org\/extra\/clang-tidy\/\">clang-tidy<\/a>\u00a0is a standalone tool used to automatically convert C++ code, written against old standards, to use features of the newest C++ standard where appropriate.<\/p>\n<p>Here are some places detected by clang-tidy where we can modernize the code:<\/p>\n<ul>\n<li>Override: Detect places where you can add the override specifier to member functions that override a virtual function in a base class and that don\u2019t already have the specifier<\/li>\n<li>Loop Convert: Detect loops like for(\u2026; \u2026; \u2026) to replace them with the new range-based loops in C++11 and give you the new range loop expression to use.<\/li>\n<li>Pass-By-Value: Detect const-ref parameters that would benefit from using the\u00a0pass-by-value idiom.<\/li>\n<li>auto_ptr: Detect the uses of the deprecated std::auto_ptr to replace by std::unique_ptr.<\/li>\n<li>auto specifier: Detect places where to use the auto type specifier in variable declarations.<\/li>\n<li>nullptr: Detect null literals to be replaced by nullptr where applicable.<\/li>\n<li>std::bind:The check finds uses of\u00a0<code class=\"docutils literal\"><span class=\"pre\">std::bind<\/span><\/code>\u00a0and replaces simple uses with lambdas. Lambdas will use value-capture where required.<\/li>\n<li>Deprecated headers:Some headers from C library were deprecated in C++ and are no longer welcome in C++ codebases. Some have no effect in C++. For more details refer to the C++ 14 Standard [depr.c.headers] section.<\/li>\n<li>std::shared_ptr: This check finds the creation of\u00a0<code class=\"docutils literal\"><span class=\"pre\">std::shared_ptr<\/span><\/code>\u00a0objects by explicitly calling the constructor and a\u00a0<code class=\"docutils literal\"><span class=\"pre\">new<\/span><\/code>\u00a0expression, and replaces it with a call to\u00a0<code class=\"docutils literal\"><span class=\"pre\">std::make_shared<\/span><\/code>.<\/li>\n<li>std::unique_ptr: This check finds the creation of\u00a0<code class=\"docutils literal\"><span class=\"pre\">std::unique_ptr<\/span><\/code>\u00a0objects by explicitly calling the constructor and a\u00a0<code class=\"docutils literal\"><span class=\"pre\">new<\/span><\/code>\u00a0expression, and replaces it with a call to\u00a0<code class=\"docutils literal\"><span class=\"pre\">std::make_unique<\/span><\/code>, introduced in C++14.<\/li>\n<li>raw string literals: This check selectively replaces string literals containing escaped characters with raw string literals.<\/li>\n<\/ul>\n<p>Developers who use Clang could easily use the clang-tidy tool. However for Visual C++ developers and other compilers you can\u00a0use\u00a0<a href=\"http:\/\/www.cppdepend.com\/\">CppDepend<\/a>\u00a0which integrate clang-tidy.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Recently the C++ community\u00a0 promotes the use of\u00a0the new standards to modernize the existing code base.\u00a0 However even before the release of the C++11 standard\u00a0some known\u00a0C++ experts\u00a0like Andrei Alexandrescu, Scott Meyers and Herb Sutter promotes the uses of the generic programming and they qualify it as Modern C++ Design.\u00a0Here\u2019s what say Andrei Alexandrescu about the &hellip; <a href=\"https:\/\/cppdepend.com\/blog\/easy-steps-to-modernize-your-c-code\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Easy steps to modernize your C++ code.&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-395","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/posts\/395","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/comments?post=395"}],"version-history":[{"count":9,"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/posts\/395\/revisions"}],"predecessor-version":[{"id":406,"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/posts\/395\/revisions\/406"}],"wp:attachment":[{"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/media?parent=395"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/categories?post=395"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/tags?post=395"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}