{"id":12655,"date":"2017-03-07T10:12:20","date_gmt":"2017-03-07T18:12:20","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/vcblog\/?p=12655"},"modified":"2019-02-18T17:48:38","modified_gmt":"2019-02-18T17:48:38","slug":"check-for-const-correctness-with-the-c-core-guidelines-checker","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cppblog\/check-for-const-correctness-with-the-c-core-guidelines-checker\/","title":{"rendered":"Check for const correctness with the C++ Core Guidelines Checker"},"content":{"rendered":"<p><em>This blog post was written by Sunny Chatterjee and Andrew Pardoe<\/em><\/p>\n<p>The <a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines\">C++ Core Guidelines<\/a> focus on simple ways that you can improve the correctness and safety of your code. We introduced the <a href=\"https:\/\/blogs.msdn.microsoft.com\/vcblog\/2016\/10\/12\/cppcorecheck\">C++ Core Guidelines Checkers<\/a> to help automate enforcement of the C++ Core Guidelines in your code.<\/p>\n<p>One of the easiest and most important changes you can make to your code is to mark immutable data as `const`. It\u2019s not us and the Core Guidelines who believe that: see <a href=\"https:\/\/randomascii.wordpress.com\/2017\/01\/08\/add-a-const-here-delete-a-const-there\/\">this fantastic blog post<\/a> from Bruce Dawson about the benefits of adding <code>const<\/code> to your code. (He also mentions that on MSVC <em>removing<\/em> <code>const<\/code> can make some code faster, but that reflects a compiler bug that we are fixing thanks to Bruce\u2019s feedback.) Because <code>const<\/code> is so important we\u2019ve added a new C++ Core Guidelines checker about <code>const<\/code> correctness.<\/p>\n<p>We created four new rules in the C++ Core Guidelines checker that cover all of the rules in the currently contained in the <a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#S-const\">Constants and Immutability<\/a> section of the C++ Core Guidelines. We didn\u2019t actually add these checks for all of the rules\u2014we implemented a check for rule #2, \u201cBy default, make member functions <code>const<\/code>\u201d but removed it because it raised too many false positives on valid code\u2014see below for details. Also, the tool will not warn that you could mark a stub function as <code>const<\/code> because we recognize that you\u2019ll probably just remove the <code>const<\/code> later when you implement the function.<\/p>\n<h3>Const checker rules<\/h3>\n<h4><a href=\"https:\/\/github.com\/isocpp\/CppCoreGuidelines\/blob\/master\/CppCoreGuidelines.md#Rconst-immutable\">Con.1: By default, make objects immutable<\/a><\/h4>\n<p>This rule is a general idea that states that we should always mark objects as <code>const<\/code> unless we\u2019re writing to them. We cover this rule through more specific implementation of subsequent rules in our checker.<\/p>\n<h4><a href=\"https:\/\/github.com\/isocpp\/CppCoreGuidelines\/blob\/master\/CppCoreGuidelines.md#Rconst-ref\">Con.3: By default, pass pointers and references to\u00a0consts<\/a><\/h4>\n<p>Our checker enforces this rule. You can pass a pointer or reference to a non-const object, but if you do so, the caller shall assume their argument will be modified. If the function does not modify the object, we should mark the object as const to make the intent explicit.<\/p>\n<h5>Advantages of this check<\/h5>\n<ul>\n<li>Makes the intention of the callee explicit to the caller about whether or not an argument will be modified.<\/li>\n<li>Future modifications in function body doesn\u2019t change the expectations of the caller.<\/li>\n<\/ul>\n<p>We use certain heuristics to reduce noise \u2013<\/p>\n<ul>\n<li>We don\u2019t ask to mark arguments that are passed by value or the pointer arguments themselves as <code>const<\/code>.<\/li>\n<li>We don\u2019t ask unused arguments be marked as <code>const<\/code> since we don\u2019t have enough information about their intent.<\/li>\n<li>We don\u2019t enforce this on virtual functions as the author may want to follow a specific derived behavior.<\/li>\n<\/ul>\n<h5>Examples<\/h5>\n<pre class=\"prettyprint\">\n\/\/ Expect 26461: The input pointer argument b in function f7 can be marked as const\nint f7(const int *a, int *b)\n{\n    return *a + *b;\n}\n\nstruct S0\n{\n    virtual void m();\n};\n\n\/\/ Expect 26461 on 'p' but don't report on unnamed parameter.\nS0 f8(int *p, int *)\n{\n    (p == nullptr);\n\n    \/\/ Don't report on return UDT.\n    return{};\n}\n<\/pre>\n<h4><a href=\"https:\/\/github.com\/isocpp\/CppCoreGuidelines\/blob\/master\/CppCoreGuidelines.md#Rconst-const\">Con.4: Use\u00a0const\u00a0to define objects with values that do not change after construction<\/a><\/h4>\n<p>Our checker enforces this rule. It\u2019s similar to con.3, but applies to all variables and not just pointer or reference arguments. It helps prevent surprise from unexpected changes in object values.<\/p>\n<h5>Advantages of this check are pretty similar to con.3<\/h5>\n<ul>\n<li>Makes it easier to reason about code if we know if an object is immutable at the point of declaration.<\/li>\n<li>Future modification of the code cannot change the immutable property of the object.<\/li>\n<\/ul>\n<p>Like con.3, we use certain heuristics to reduce noise \u2013<\/p>\n<ul>\n<li>We avoid suggesting const usage on un-used variables \u2013 they rarely add any value.<\/li>\n<li>We don\u2019t suggest to mark the pointer or reference themselves as <code>const<\/code>, since users mostly care about the data that they point to.<\/li>\n<\/ul>\n<h5>Examples<\/h5>\n<pre class=\"prettyprint\">\nint f5()\n{\n    \/\/ Expect 26496: Variable m is assigned only once, use const.\n    int m = 5;\n    const int a = 10;\n    if (m &gt; a)\n        return m;\n    return a;\n}\n<\/pre>\n<h4><a href=\"https:\/\/github.com\/isocpp\/CppCoreGuidelines\/blob\/master\/CppCoreGuidelines.md#Rconst-constexpr\">Con.5: Use\u00a0constexpr\u00a0for values that can be computed at compile time<\/a> and <a href=\"https:\/\/github.com\/isocpp\/CppCoreGuidelines\/blob\/master\/CppCoreGuidelines.md#f4-if-a-function-may-have-to-be-evaluated-at-compile-time-declare-it-constexpr\">F.4: If a function may have to be evaluated at compile time, declare it\u00a0constexpr<\/a><\/h4>\n<p>Our checker encourages programmers to declare functions that may have to be evaluated at compile time as <code>constexpr<\/code>.<\/p>\n<h5>Examples<\/h5>\n<pre class=\"prettyprint\">\n\/\/ Expect 26497: could be marked constexpr if compile-time evaluation is desired\nint f1(int a, int b)\n{\n    return a + b;\n}\n\nconstexpr int f2(int a, int b)\n{\n    return a + b;\n}\n\nvoid f3()\n{\n   \/\/ Compile-time evaluation\n    constexpr int m = f2(10, 20);\n    \n    \/\/ Expect 26498: This function call f2 can use constexpr if compile-time evaluation is desired.\n    const int m2 = f2(10, 20);\n}\n<\/pre>\n<h4>Rule 2: the one we didn\u2019t include<\/h4>\n<h4><a href=\"https:\/\/github.com\/isocpp\/CppCoreGuidelines\/blob\/master\/CppCoreGuidelines.md#Rconst-fct\">Con.2: By default, make member functions\u00a0const<\/a><\/h4>\n<p>In the initial prototype, we included this check. However, after running this check on some real-world code, we decided to remove it from the shipping version of the checker. We didn\u2019t want programmers to mark their member functions as <code>const<\/code> when they were logically non-<code>const<\/code>. For the intrepid, there\u2019s a good discussion of logical and physical constness on the isocpp.org web page: <a href=\"https:\/\/isocpp.org\/wiki\/faq\/const-correctness#logical-vs-physical-state\">https:\/\/isocpp.org\/wiki\/faq\/const-correctness#logical-vs-physical-state<\/a>.<\/p>\n<p>Here\u2019s an example where the member function is logically non-const. You could mark member function <code>bar<\/code> as <code>const<\/code>, e.g., <code>void bar() const { *data_\u00a0 = GetData(); }<\/code>. While it doesn\u2019t alter the pointer <code>data_<\/code> itself, it could alter the memory pointed to by <code>data_<\/code>. Thus this function is not logically <code>const<\/code>.<\/p>\n<pre class=\"prettyprint\">\nclass Test\n{\npublic:\n    \/\/ This method should be marked \u201cconst\u201d since it doesn\u2019t change the logical state of the object.\n    MyData foo() const { return *data_; } \n    \n    \/\/ This method shouldn\u2019t be blindly marked as \u201cconst\u201d. It doesn\u2019t alter the pointer data_ itself.\n    \/\/ However, it alters the state of memory pointed-to by it.\n    void bar() const { *data_ = GetData(); }\n\nprivate:\n    \/\/ data_ is a pointer to a \u201cMyData\u201d object\n    MyData *data_;\n};\n<\/pre>\n<p>&nbsp;<\/p>\n<h4>Send us your feedback!<\/h4>\n<p>As always, we welcome your feedback. For problems, let us know via the Report a Problem option, either from the installer or the Visual Studio IDE itself.For suggestions, let us know through <a href=\"https:\/\/visualstudio.uservoice.com\/forums\/121579-visual-studio-2015\/category\/30937-languages-c\">UserVoice<\/a>. And you can always reach us through e-mail at cppcorecheck@microsoft.com.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This blog post was written by Sunny Chatterjee and Andrew Pardoe The C++ Core Guidelines focus on simple ways that you can improve the correctness and safety of your code. We introduced the C++ Core Guidelines Checkers to help automate enforcement of the C++ Core Guidelines in your code. One of the easiest and most [&hellip;]<\/p>\n","protected":false},"author":324,"featured_media":35994,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[270],"tags":[245,163],"class_list":["post-12655","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-announcement","tag-cppcorecheck","tag-static-analysis"],"acf":[],"blog_post_summary":"<p>This blog post was written by Sunny Chatterjee and Andrew Pardoe The C++ Core Guidelines focus on simple ways that you can improve the correctness and safety of your code. We introduced the C++ Core Guidelines Checkers to help automate enforcement of the C++ Core Guidelines in your code. One of the easiest and most [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/12655","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/users\/324"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/comments?post=12655"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/12655\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media\/35994"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media?parent=12655"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/categories?post=12655"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/tags?post=12655"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}