{"id":5381,"date":"2018-02-03T07:50:58","date_gmt":"2018-02-03T07:50:58","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-rules\/"},"modified":"2023-06-26T11:58:18","modified_gmt":"2023-06-26T11:58:18","slug":"c-core-guidelines-rules","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-rules\/","title":{"rendered":"C++ Core Guidelines: More Rules for Expressions"},"content":{"rendered":"<p>I know this post&#8217;s headline is a bit boring: More Rules for Expressions. Honestly, this post is about code hygiene because I will mainly write about pointers.<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5379\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/02\/dental.png\" alt=\"dental\" width=\"400\" height=\"234\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/02\/dental.png 960w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/02\/dental-300x176.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/02\/dental-768x450.png 768w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/p>\n<p>Let&#8217;s have a look at my plan for today.<\/p>\n<ul style=\"margin-top: 0px; margin-bottom: 1rem; color: #515151; font-family: 'PT Sans', Helvetica, Arial, sans-serif; font-size: 20px; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff;\">\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Res-ptr\" style=\"color: #268bd2; text-decoration: none;\">ES.42: Keep use of pointers simple and straightforward<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Res-magic\" style=\"color: #268bd2; text-decoration: none;\">ES.45: Avoid \u201cmagic constants\u201d; use symbolic constants<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Res-magic\" style=\"color: #268bd2; text-decoration: none;\"><\/a><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Res-nullptr\" style=\"color: #268bd2; text-decoration: none;\">ES.47: Use&nbsp;<code class=\"highlighter-rouge no-highlight\" style=\"font-family: 'Roboto Mono', monospace; padding: 0.2em; font-size: 18px; background-color: #f9f9f9;\">nullptr<\/code>&nbsp;rather than&nbsp;<code class=\"highlighter-rouge no-highlight\" style=\"font-family: 'Roboto Mono', monospace; padding: 0.2em; font-size: 18px; background-color: #f9f9f9;\">0<\/code>&nbsp;or&nbsp;<code class=\"highlighter-rouge no-highlight\" style=\"font-family: 'Roboto Mono', monospace; padding: 0.2em; font-size: 18px; background-color: #f9f9f9;\">NULL<\/code><\/a><\/li>\n<\/ul>\n<p>I will start with a significant rule.<\/p>\n<h3><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Res-ptr\" style=\"color: #268bd2; text-decoration: none;\">ES.42: Keep use of pointers simple and straightforward<\/a><\/h3>\n<p>Let me cite the words of the guidelines: &#8220;<em>Complicated pointer manipulation is a major source of errors<\/em>.&#8221;. Why should we care? Of course, our legacy code is full of functionality, such as this example:<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">f<\/span>(<span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">*<\/span> p, <span style=\"color: #007788; font-weight: bold;\">int<\/span> count)\r\n{\r\n    <span style=\"color: #006699; font-weight: bold;\">if<\/span> (count <span style=\"color: #555555;\">&lt;<\/span> <span style=\"color: #ff6600;\">2<\/span>) <span style=\"color: #006699; font-weight: bold;\">return<\/span>;\r\n\r\n    <span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">*<\/span> q <span style=\"color: #555555;\">=<\/span> p <span style=\"color: #555555;\">+<\/span> <span style=\"color: #ff6600;\">1<\/span>;    <span style=\"color: #0099ff; font-style: italic;\">\/\/ BAD<\/span>\r\n\r\n    <span style=\"color: #007788; font-weight: bold;\">int<\/span> n <span style=\"color: #555555;\">=<\/span> <span style=\"color: #555555;\">*<\/span>p<span style=\"color: #555555;\">++<\/span>;      <span style=\"color: #0099ff; font-style: italic;\">\/\/ BAD<\/span>\r\n\r\n    <span style=\"color: #006699; font-weight: bold;\">if<\/span> (count <span style=\"color: #555555;\">&lt;<\/span> <span style=\"color: #ff6600;\">6<\/span>) <span style=\"color: #006699; font-weight: bold;\">return<\/span>;\r\n\r\n    p[<span style=\"color: #ff6600;\">4<\/span>] <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">1<\/span>;          <span style=\"color: #0099ff; font-style: italic;\">\/\/ BAD<\/span>\r\n\r\n    p[count <span style=\"color: #555555;\">-<\/span> <span style=\"color: #ff6600;\">1<\/span>] <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">2<\/span>;  <span style=\"color: #0099ff; font-style: italic;\">\/\/ BAD<\/span>\r\n\r\n    use(<span style=\"color: #555555;\">&amp;<\/span>p[<span style=\"color: #ff6600;\">0<\/span>], <span style=\"color: #ff6600;\">3<\/span>);     <span style=\"color: #0099ff; font-style: italic;\">\/\/ BAD<\/span>\r\n}\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> myArray[<span style=\"color: #ff6600;\">100<\/span>];     <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n\r\nf(myArray, <span style=\"color: #ff6600;\">100<\/span>),      <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The main issue with&nbsp;this code is that the caller&nbsp;must&nbsp;provide the&nbsp;correct length of the&nbsp;C-array. If not, we&nbsp;have undefined behavior.<\/p>\n<p>Think about the last lines (1) and (2) for a few seconds. We start with an array and remove its type information by passing it to the function f. This process is called an array-to-pointer decay and is the reason for many errors. Maybe we had a bad day, and we&nbsp;count the number of elements wrong, or the size of the C-array changed. Anyway, the result is always the same: undefined behavior. The same argumentation will also hold for a C-string.<\/p>\n<p>What should we do? We should use the right data type. The Guidelines suggest using&nbsp;gsl<span style=\"font-family: 'courier new', courier;\">:<\/span>:span<span style=\"font-family: 'courier new', courier;\"><\/span>type from the <a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#S-gsl\">Guidelines Support Library<\/a>&nbsp;(GSL). Have a look here:<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">f<\/span>(span<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span> a) <span style=\"color: #0099ff; font-style: italic;\">\/\/ BETTER: use span in the function declaration<\/span>\r\n{\r\n    <span style=\"color: #006699; font-weight: bold;\">if<\/span> (a.length() <span style=\"color: #555555;\">&lt;<\/span> <span style=\"color: #ff6600;\">2<\/span>) <span style=\"color: #006699; font-weight: bold;\">return<\/span>;\r\n\r\n    <span style=\"color: #007788; font-weight: bold;\">int<\/span> n <span style=\"color: #555555;\">=<\/span> a[<span style=\"color: #ff6600;\">0<\/span>];      <span style=\"color: #0099ff; font-style: italic;\">\/\/ OK<\/span>\r\n\r\n    span<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span> q <span style=\"color: #555555;\">=<\/span> a.subspan(<span style=\"color: #ff6600;\">1<\/span>); <span style=\"color: #0099ff; font-style: italic;\">\/\/ OK<\/span>\r\n\r\n    <span style=\"color: #006699; font-weight: bold;\">if<\/span> (a.length() <span style=\"color: #555555;\">&lt;<\/span> <span style=\"color: #ff6600;\">6<\/span>) <span style=\"color: #006699; font-weight: bold;\">return<\/span>;\r\n\r\n    a[<span style=\"color: #ff6600;\">4<\/span>] <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">1<\/span>;          <span style=\"color: #0099ff; font-style: italic;\">\/\/ OK<\/span>\r\n\r\n    a[count <span style=\"color: #555555;\">-<\/span> <span style=\"color: #ff6600;\">1<\/span>] <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">2<\/span>;  <span style=\"color: #0099ff; font-style: italic;\">\/\/ OK<\/span>\r\n\r\n    use(a.data(), <span style=\"color: #ff6600;\">3<\/span>);  <span style=\"color: #0099ff; font-style: italic;\">\/\/ OK<\/span>\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Fine!&nbsp;<span style=\"font-family: 'courier new', courier;\">gsl::span<\/span> checks at run-time its boundaries. Additionally, the Guidelines Support Library has a free function <span style=\"font-family: 'courier new', courier;\">at<\/span> for accessing the elements of an <span style=\"font-family: 'courier new', courier;\">gsl::span.<\/span>&nbsp;<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">f3<\/span>(array<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span>, <span style=\"color: #ff6600;\">10<\/span><span style=\"color: #555555;\">&gt;<\/span> a, <span style=\"color: #007788; font-weight: bold;\">int<\/span> pos) \r\n{\r\n    at(a, pos <span style=\"color: #555555;\">\/<\/span> <span style=\"color: #ff6600;\">2<\/span>) <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">1<\/span>;       <span style=\"color: #0099ff; font-style: italic;\">\/\/ OK<\/span>\r\n    at(a, pos <span style=\"color: #555555;\">-<\/span> <span style=\"color: #ff6600;\">1<\/span>) <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">2<\/span>;       <span style=\"color: #0099ff; font-style: italic;\">\/\/ OK<\/span>\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>I know your issue. Most of you don&#8217;t use the Guidelines Support Library. No problem. It&#8217;s quite easy to rewrite the functions <span style=\"font-family: 'courier new', courier;\">f<\/span> and <span style=\"font-family: 'courier new', courier;\">f3 <\/span>using the container&nbsp;<span style=\"font-family: 'courier new', courier;\">std:<\/span>:<span style=\"font-family: 'courier new', courier;\">array<\/span> and the method&nbsp;<span style=\"font-family: 'courier new', courier;\">std::array::at<\/span>. Here we are:<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ spanVersusArray.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;algorithm&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;array&gt;<\/span>\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">use<\/span>(<span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">*<\/span>, <span style=\"color: #007788; font-weight: bold;\">int<\/span>){}\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">f<\/span>(std<span style=\"color: #555555;\">::<\/span>array<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span>, <span style=\"color: #ff6600;\">100<\/span><span style=\"color: #555555;\">&gt;&amp;<\/span> a){\r\n\r\n    <span style=\"color: #006699; font-weight: bold;\">if<\/span> (a.size() <span style=\"color: #555555;\">&lt;<\/span> <span style=\"color: #ff6600;\">2<\/span>) <span style=\"color: #006699; font-weight: bold;\">return<\/span>;\r\n\r\n    <span style=\"color: #007788; font-weight: bold;\">int<\/span> n <span style=\"color: #555555;\">=<\/span> a.at(<span style=\"color: #ff6600;\">0<\/span>);      \r\n\r\n    std<span style=\"color: #555555;\">::<\/span>array<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span>, <span style=\"color: #ff6600;\">99<\/span><span style=\"color: #555555;\">&gt;<\/span> q;\r\n    std<span style=\"color: #555555;\">::<\/span>copy(a.begin() <span style=\"color: #555555;\">+<\/span> <span style=\"color: #ff6600;\">1<\/span>, a.end(), q.begin());      <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n\r\n    <span style=\"color: #006699; font-weight: bold;\">if<\/span> (a.size() <span style=\"color: #555555;\">&lt;<\/span> <span style=\"color: #ff6600;\">6<\/span>) <span style=\"color: #006699; font-weight: bold;\">return<\/span>;\r\n\r\n    a.at(<span style=\"color: #ff6600;\">4<\/span>) <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">1<\/span>;          \r\n\r\n    a.at(a.size() <span style=\"color: #555555;\">-<\/span> <span style=\"color: #ff6600;\">1<\/span>) <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">2<\/span>;\r\n\r\n    use(a.data(), <span style=\"color: #ff6600;\">3<\/span>); \r\n}\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">f3<\/span>(std<span style=\"color: #555555;\">::<\/span>array<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span>, <span style=\"color: #ff6600;\">10<\/span><span style=\"color: #555555;\">&gt;<\/span> a, <span style=\"color: #007788; font-weight: bold;\">int<\/span> pos){\r\n    a.at(pos <span style=\"color: #555555;\">\/<\/span> <span style=\"color: #ff6600;\">2<\/span>) <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">1<\/span>;      \r\n    a.at(pos <span style=\"color: #555555;\">-<\/span> <span style=\"color: #ff6600;\">1<\/span>) <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">2<\/span>; \r\n}\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>(){\r\n\r\n    std<span style=\"color: #555555;\">::<\/span>array<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span>, <span style=\"color: #ff6600;\">100<\/span><span style=\"color: #555555;\">&gt;<\/span> arr{};\r\n\r\n    f(arr);\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>array<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span>, <span style=\"color: #ff6600;\">10<\/span><span style=\"color: #555555;\">&gt;<\/span> arr2{};\r\n \r\n    f3(arr2, <span style=\"color: #ff6600;\">6<\/span>);\r\n\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The <span style=\"font-family: 'courier new', courier;\">std:<\/span>:<span style=\"font-family: 'courier new', courier;\">array::at<\/span> Operator will check at runtime its bounds. If <span style=\"font-family: 'courier new', courier;\">pos &gt;= size()<\/span>, you will get an <a href=\"http:\/\/en.cppreference.com\/w\/cpp\/error\/out_of_range\"><span style=\"font-family: 'courier new', courier;\">std::out_of_range<\/span><\/a><span style=\"color: #000000; font-family: DejaVuSans, 'DejaVu Sans', arial, sans-serif; font-size: 12.8px; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff; float: none;\">&nbsp;exception. <\/span><span style=\"color: #000000; font-family: DejaVuSans, 'DejaVu Sans', arial, sans-serif; font-size: 12.8px; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff; float: none;\">Looking carefully at the <span style=\"font-family: 'courier new', courier;\">spanVersusArray.cpp<\/span>&nbsp;program, you will notice two issues. First, the expression (1) is more verbose than the gsl<span style=\"font-family: 'courier new', courier;\">:<\/span>:span version and second, the size of the <span style=\"font-family: 'courier new', courier;\">std:<\/span>:array is part of the signature of the function&nbsp;<span style=\"font-family: 'courier new', courier;\">f.<\/span> This is bad. I can only use f with the type <span style=\"font-family: 'courier new', courier;\">std:<\/span>:array<span style=\"font-family: 'courier new', courier;\">&lt;int, 100&gt;<\/span>.&nbsp; In this case, the checks of the array size inside the function are superfluous.&nbsp;<\/span><\/p>\n<p>To your rescue, C++ has templates; therefore, it&#8217;s easy to overcome the type restrictions but stay type-safe.<\/p>\n<p>&nbsp;<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ at.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;algorithm&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;array&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;deque&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;string&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;vector&gt;<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span> <span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">typename<\/span> T<span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> use(T<span style=\"color: #555555;\">*<\/span>, <span style=\"color: #007788; font-weight: bold;\">int<\/span>){}\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span> <span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">typename<\/span> T<span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> f(T<span style=\"color: #555555;\">&amp;<\/span> a){\r\n\r\n    <span style=\"color: #006699; font-weight: bold;\">if<\/span> (a.size() <span style=\"color: #555555;\">&lt;<\/span> <span style=\"color: #ff6600;\">2<\/span>) <span style=\"color: #006699; font-weight: bold;\">return<\/span>;\r\n\r\n    <span style=\"color: #007788; font-weight: bold;\">int<\/span> n <span style=\"color: #555555;\">=<\/span> a.at(<span style=\"color: #ff6600;\">0<\/span>);      \r\n\r\n    std<span style=\"color: #555555;\">::<\/span>array<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">typename<\/span> T<span style=\"color: #555555;\">::<\/span>value_type , <span style=\"color: #ff6600;\">99<\/span><span style=\"color: #555555;\">&gt;<\/span> q;                 <span style=\"color: #0099ff; font-style: italic;\">\/\/ (4)<\/span>\r\n    std<span style=\"color: #555555;\">::<\/span>copy(a.begin() <span style=\"color: #555555;\">+<\/span> <span style=\"color: #ff6600;\">1<\/span>, a.end(), q.begin());     \r\n\r\n    <span style=\"color: #006699; font-weight: bold;\">if<\/span> (a.size() <span style=\"color: #555555;\">&lt;<\/span> <span style=\"color: #ff6600;\">6<\/span>) <span style=\"color: #006699; font-weight: bold;\">return<\/span>;\r\n\r\n    a.at(<span style=\"color: #ff6600;\">4<\/span>) <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">1<\/span>;          \r\n\r\n    a.at(a.size() <span style=\"color: #555555;\">-<\/span> <span style=\"color: #ff6600;\">1<\/span>) <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">2<\/span>;\r\n\r\n    use(a.data(), <span style=\"color: #ff6600;\">3<\/span>);                                          <span style=\"color: #0099ff; font-style: italic;\">\/\/ (5)<\/span>\r\n}\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> main(){\r\n\r\n    std<span style=\"color: #555555;\">::<\/span>array<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span>, <span style=\"color: #ff6600;\">100<\/span><span style=\"color: #555555;\">&gt;<\/span> arr{};                                             \r\n    f(arr);                                                    <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>array<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">double<\/span>, <span style=\"color: #ff6600;\">20<\/span><span style=\"color: #555555;\">&gt;<\/span> arr2{};\r\n    f(arr2);                                                   <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>vector<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">double<\/span><span style=\"color: #555555;\">&gt;<\/span> vec{<span style=\"color: #ff6600;\">1<\/span>, <span style=\"color: #ff6600;\">2<\/span>, <span style=\"color: #ff6600;\">3<\/span>, <span style=\"color: #ff6600;\">4<\/span>, <span style=\"color: #ff6600;\">5<\/span>, <span style=\"color: #ff6600;\">6<\/span>, <span style=\"color: #ff6600;\">7<\/span>, <span style=\"color: #ff6600;\">8<\/span>, <span style=\"color: #ff6600;\">9<\/span>};\r\n    f(vec);                                                    <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span>\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>string myString<span style=\"color: #555555;\">=<\/span> <span style=\"color: #cc3300;\">\"123456789\"<\/span>;\r\n    f(myString);                                               <span style=\"color: #0099ff; font-style: italic;\">\/\/ (4)<\/span>\r\n    \r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ std::deque&lt;int&gt; deq{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};<\/span>\r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ f(deq);                                                 \/\/ (5)<\/span>\r\n    \r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Now, the function f works for <span style=\"font-family: 'courier new', courier;\">std:<\/span>:array&#8217;s of different sizes and types (lines (1) and (2)) but also for a <span style=\"font-family: 'courier new', courier;\">std:<\/span>:vector<span style=\"font-family: 'courier new', courier;\"><\/span>(3) or a <span style=\"font-family: 'courier new', courier;\">std:<\/span>:string&nbsp;(4). This container has in common that its data is stored in a&nbsp;contiguous memory block. This will not hold <span style=\"font-family: 'courier new', courier;\">std::deque;<\/span> therefore, the call <span style=\"font-family: 'courier new', courier;\">a.data()<\/span> in expression (5) fails. A std<span style=\"font-family: 'courier new', courier;\">:<\/span>:deque is a kind of doubly-linked list of small memory blocks.<\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5380\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/02\/deque.png\" alt=\"deque\" width=\"500\" height=\"38\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/02\/deque.png 2174w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/02\/deque-300x22.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/02\/deque-1024x76.png 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/02\/deque-768x57.png 768w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/02\/deque-1536x114.png 1536w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/02\/deque-2048x152.png 2048w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><\/p>\n<p>The expression&nbsp;<span style=\"font-family: 'courier new', courier;\">T::value_type<\/span> (5) helps me get each container&#8217;s underlying value type. <span style=\"font-family: 'courier new', courier;\">T<\/span> is a so-called dependent type because <span style=\"font-family: 'courier new', courier;\">T<\/span> is a type parameter of the function template <span style=\"font-family: 'courier new', courier;\">f<\/span>. This is the reason I have to give the compiler a hint that <span style=\"font-family: 'courier new', courier;\">T::value_type<\/span> is a type:&nbsp;<span style=\"font-family: 'courier new', courier;\">typename T::value_type<\/span>.<\/p>\n<\/p>\n<h3><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Res-magic\" style=\"color: #268bd2; text-decoration: none;\">ES.45: Avoid \u201cmagic constants\u201d; use symbolic constants<\/a><\/h3>\n<p>This is obvious: A symbolic constant says more than a magic constant.&nbsp;<\/p>\n<p>The guidelines start with a magic constant, continue with a symbolic constant, and finish with a range-based for loop.&nbsp;<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #007788; font-weight: bold;\">int<\/span> m <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">1<\/span>; m <span style=\"color: #555555;\">&lt;=<\/span> <span style=\"color: #ff6600;\">12<\/span>; <span style=\"color: #555555;\">++<\/span>m)        <span style=\"color: #0099ff; font-style: italic;\">\/\/ don't: magic constant 12<\/span>\r\n    cout <span style=\"color: #555555;\">&lt;&lt;<\/span> month[m] <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n\r\n\r\n\r\n                  <span style=\"color: #0099ff; font-style: italic;\">\/\/ months are indexed 1..12 (symbolic constant)<\/span>\r\nconstexpr <span style=\"color: #007788; font-weight: bold;\">int<\/span> first_month <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">1<\/span>;\r\nconstexpr <span style=\"color: #007788; font-weight: bold;\">int<\/span> last_month <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">12<\/span>;\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #007788; font-weight: bold;\">int<\/span> m <span style=\"color: #555555;\">=<\/span> first_month; m <span style=\"color: #555555;\">&lt;=<\/span> last_month; <span style=\"color: #555555;\">++<\/span>m)        <span style=\"color: #0099ff; font-style: italic;\">\/\/ better<\/span>\r\n    cout <span style=\"color: #555555;\">&lt;&lt;<\/span> month[m] <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n\r\n\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #006699; font-weight: bold;\">auto<\/span> m <span style=\"color: #555555;\">:<\/span> month)          <span style=\"color: #0099ff; font-style: italic;\">\/\/ the best (ranged-based for loop)<\/span>\r\n    cout <span style=\"color: #555555;\">&lt;&lt;<\/span> m <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>In the case of the ranged-based for loop, it is not possible to make an <a href=\"https:\/\/en.wikipedia.org\/wiki\/Off-by-one_error\">off-by-one <\/a>error.&nbsp;&nbsp;<\/p>\n<p>Let me directly jump to the rule ES.47. I want to put the rules for conversion, including ES.46, in a separate post.<\/p>\n<h3><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Res-nullptr\" style=\"color: #268bd2; text-decoration: none;\"><span style=\"color: #268bd2;\">ES.47: Use&nbsp;<\/span><code class=\"highlighter-rouge no-highlight\" style=\"font-family: 'Roboto Mono', monospace; padding: 0.2em; font-size: 18px; background-color: #f9f9f9;\">nullptr<\/code><span style=\"color: #268bd2;\">&nbsp;rather than&nbsp;<\/span><code class=\"highlighter-rouge no-highlight\" style=\"font-family: 'Roboto Mono', monospace; padding: 0.2em; font-size: 18px; background-color: #f9f9f9;\">0<\/code><span style=\"color: #268bd2;\">&nbsp;or&nbsp;<\/span><code class=\"highlighter-rouge no-highlight\" style=\"font-family: 'Roboto Mono', monospace; padding: 0.2em; font-size: 18px; background-color: #f9f9f9;\">NULL<\/code><\/a><\/h3>\n<p>There are many reasons to use a <span style=\"font-family: 'courier new', courier;\">nullptr<\/span> instead of the number 0 or the macro <span style=\"font-family: 'courier new', courier;\">NULL<\/span>. In particular, 0 or <span style=\"font-family: 'courier new', courier;\">NULL<\/span> will not work in generic. I have already written a post about these three kinds of null pointers. Here are the details: <a href=\"https:\/\/www.modernescpp.com\/index.php\/the-null-pointer-constant-nullptr\">The Null Pointer Constant <span style=\"font-family: 'courier new', courier;\">nullptr<\/span><\/a>.<\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>How many explicit casts do we have in modern C++? Maybe your number is four, but this is the wrong number. In C++11, we have six explicit casts. When I Include the GSL, we have eight explicit casts. I will write about the eight casts in the next post.<\/p>\n<p>&nbsp;<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I know this post&#8217;s headline is a bit boring: More Rules for Expressions. Honestly, this post is about code hygiene because I will mainly write about pointers.<\/p>\n","protected":false},"author":21,"featured_media":5379,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[372],"tags":[495],"class_list":["post-5381","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-modern-c","tag-expressions"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5381","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/users\/21"}],"replies":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/comments?post=5381"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5381\/revisions"}],"predecessor-version":[{"id":6842,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5381\/revisions\/6842"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5379"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5381"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5381"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5381"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}