{"id":1729,"date":"2018-06-04T17:00:04","date_gmt":"2018-06-04T16:00:04","guid":{"rendered":"http:\/\/www.nuonsoft.com\/blog\/?p=1729"},"modified":"2018-06-03T12:55:26","modified_gmt":"2018-06-03T11:55:26","slug":"c17-fallthrough-in-switch-statements","status":"publish","type":"post","link":"https:\/\/www.nuonsoft.com\/blog\/2018\/06\/04\/c17-fallthrough-in-switch-statements\/","title":{"rendered":"C++17: Fallthrough in switch statements"},"content":{"rendered":"<p>A C++ <strong>switch<\/strong> statement allows execution to fall through from one case to the next case when a <strong>break <\/strong>statement is missing. For example:<\/p>\n<pre class=\"brush: cpp; highlight: [29,30,31]; title: ; notranslate\" title=\"\">#include &lt;iostream&gt;\r\n\r\nusing namespace std;\r\n\r\nenum class Mode\r\n{\r\n    Default,\r\n    Custom\r\n};\r\n\r\nclass Parameters {};\r\n\r\nParameters AskUserForCustomParameters()\r\n{\r\n    cout &lt;&lt; &quot;Asking user for custom parameters...&quot; &lt;&lt; endl;\r\n    return Parameters();\r\n}\r\n\r\nvoid Process(const Parameters&amp; parameters)\r\n{\r\n    cout &lt;&lt; &quot;Processing parameters...&quot; &lt;&lt; endl;\r\n}\r\n\r\nvoid DoSomething(Mode mode)\r\n{\r\n    Parameters parameters;  \/\/ Create a default set of parameters\r\n    switch (mode)\r\n    {\r\n    case Mode::Custom:\r\n        AskUserForCustomParameters();\r\n    case Mode::Default:\r\n        Process(parameters);\r\n        break;\r\n    }\r\n}\r\n\r\nint main()\r\n{\r\n    DoSomething(Mode::Custom);\r\n\r\n    cout &lt;&lt; endl;\r\n\r\n    DoSomething(Mode::Default);\r\n}<\/pre>\n<p>Of course, in this case we could just have used an <strong>if<\/strong> statement, but that wouldn&#8217;t demonstrate fallthrough in <strong>switch<\/strong> statements.<\/p>\n<p>If you look at the code, the case for <strong>Mode::Custom<\/strong> does not contain a <strong>break<\/strong> statement. Some compilers will issue a warning for this kind of fallthrough because it might be unintended and a source of bugs. C++17 introduced a <strong>[[fallthrough]]<\/strong> attribute that you can use to specify in code that a fallthrough is intentional and should not generate a warning. Here is the modified fragment:<\/p>\n<pre class=\"brush: cpp; highlight: [8]; title: ; notranslate\" title=\"\">void DoSomething(Mode mode)\r\n{\r\n    Parameters parameters;  \/\/ Create a default set of parameters\r\n    switch (mode)\r\n    {\r\n    case Mode::Custom:\r\n        AskUserForCustomParameters();\r\n        &#x5B;&#x5B;fallthrough]];\r\n    case Mode::Default:\r\n        Process(parameters);\r\n        break;\r\n    }\r\n}<\/pre>\n<p>You don&#8217;t need to use the <strong>[[fallthrough]]<\/strong> attribute for empty <strong>switch<\/strong> cases. No compiler will issue a warning for fallthrough with empty <strong>case<\/strong> statements. For example:<\/p>\n<pre class=\"brush: cpp; highlight: [5,16,17]; title: ; notranslate\" title=\"\">enum class Mode\r\n{\r\n    Default,\r\n    Custom,\r\n    Standard\r\n};\r\n\r\nvoid DoSomething(Mode mode)\r\n{\r\n    Parameters parameters;  \/\/ Create a default set of parameters\r\n    switch (mode)\r\n    {\r\n    case Mode::Custom:\r\n        AskUserForCustomParameters();\r\n        &#x5B;&#x5B;fallthrough]];\r\n    case Mode::Standard:\r\n    case Mode::Default:\r\n        Process(parameters);\r\n        break;\r\n    }\r\n}<\/pre>\n<p>My book, <a href=\"https:\/\/amzn.to\/2JjvkWe\" rel=\"noopener\" target=\"_blank\">Professional C++, 4th Edition<\/a>, explains all new C++17 features, and much more.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A C++ switch statement allows execution to fall through from one case to the next case when a break statement is missing. For example: #include &lt;iostream&gt; using namespace std; enum class Mode { Default, Custom }; class Parameters {}; Parameters AskUserForCustomParameters() { cout &lt;&lt; &quot;Asking user for custom parameters&#8230;&quot; &lt;&lt; endl; return Parameters(); } void [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6],"tags":[222,228],"class_list":["post-1729","post","type-post","status-publish","format-standard","hentry","category-c","tag-c17","tag-visual-c-2017"],"_links":{"self":[{"href":"https:\/\/www.nuonsoft.com\/blog\/wp-json\/wp\/v2\/posts\/1729","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.nuonsoft.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.nuonsoft.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.nuonsoft.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.nuonsoft.com\/blog\/wp-json\/wp\/v2\/comments?post=1729"}],"version-history":[{"count":9,"href":"https:\/\/www.nuonsoft.com\/blog\/wp-json\/wp\/v2\/posts\/1729\/revisions"}],"predecessor-version":[{"id":1742,"href":"https:\/\/www.nuonsoft.com\/blog\/wp-json\/wp\/v2\/posts\/1729\/revisions\/1742"}],"wp:attachment":[{"href":"https:\/\/www.nuonsoft.com\/blog\/wp-json\/wp\/v2\/media?parent=1729"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.nuonsoft.com\/blog\/wp-json\/wp\/v2\/categories?post=1729"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.nuonsoft.com\/blog\/wp-json\/wp\/v2\/tags?post=1729"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}