{"id":5300,"date":"2017-08-11T06:17:01","date_gmt":"2017-08-11T06:17:01","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-semantic-of-function-parameter-and-return-values\/"},"modified":"2023-06-26T12:08:41","modified_gmt":"2023-06-26T12:08:41","slug":"c-core-guidelines-semantic-of-function-parameter-and-return-values","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-semantic-of-function-parameter-and-return-values\/","title":{"rendered":"C++ Core Guidelines: Semantic of Function Parameters and Return Values"},"content":{"rendered":"<p>Today,&nbsp; I conclude my treatise about the rules for functions in the C++ core guidelines. The <a href=\"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-how-to-pass-function-parameters\">last post<\/a> was about the syntax of function parameters and return values. This post, with its roughly 15 rules, is about their semantics.<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<\/p>\n<p>Before I dive into the details, here is an overview of the semantic rules for parameters, the semantic rules of return values, and a few further rules for functions.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" alignright size-full wp-image-5288\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/07\/cogs.jpg\" alt=\"cogs\" width=\"400\" height=\"300\" style=\"float: right;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/07\/cogs.jpg 640w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/07\/cogs-300x225.jpg 300w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/p>\n<p><strong>Parameter passing semantic rules:<\/strong><\/p>\n<ul>\n<li><a href=\"https:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rf-ptr\">F.22: Use <code class=\"highlighter-rouge no-highlight\">T*<\/code> or <code class=\"highlighter-rouge no-highlight\">owner&lt;T*&gt;<\/code> to designate a single object<\/a><\/li>\n<li><a href=\"https:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rf-nullptr\">F.23: Use a <code class=\"highlighter-rouge no-highlight\">not_null&lt;T&gt;<\/code> to indicate \u201cnull\u201d is not a valid value<\/a><\/li>\n<li><a href=\"https:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rf-range\">F.24: Use a <code class=\"highlighter-rouge no-highlight\">span&lt;T&gt;<\/code> or a <code class=\"highlighter-rouge no-highlight\">span_p&lt;T&gt;<\/code> to designate a half-open sequence<\/a><\/li>\n<li><a href=\"https:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rf-zstring\">F.25: Use a <code class=\"highlighter-rouge no-highlight\">zstring<\/code> or a <code class=\"highlighter-rouge no-highlight\">not_null&lt;zstring&gt;<\/code> to designate a C-style string<\/a><\/li>\n<li><a href=\"https:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rf-unique_ptr\">F.26: Use a <code class=\"highlighter-rouge no-highlight\">unique_ptr&lt;T&gt;<\/code> to transfer ownership where a pointer is needed<\/a><\/li>\n<li><a href=\"https:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rf-shared_ptr\">F.27: Use a <code class=\"highlighter-rouge no-highlight\">shared_ptr&lt;T&gt;<\/code> to share ownership<\/a><\/li>\n<\/ul>\n<p><strong>Value return semantic rules:<\/strong><\/p>\n<ul>\n<li><a href=\"https:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rf-return-ptr\">F.42: Return a <code class=\"highlighter-rouge no-highlight\">T*<\/code> to indicate a position (only)<\/a><\/li>\n<li><a href=\"https:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rf-dangle\">F.43: Never (directly or indirectly) return a pointer or a reference to a local object<\/a><\/li>\n<li><a href=\"https:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rf-return-ref\">F.44: Return a <code class=\"highlighter-rouge no-highlight\">T&amp;<\/code> when the copy is undesirable and \u201creturning no object\u201d isn\u2019t an option<\/a><\/li>\n<li><a href=\"https:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rf-return-ref-ref\">F.45: Don\u2019t return a <code class=\"highlighter-rouge no-highlight\">T&amp;&amp;<\/code><\/a><\/li>\n<li><a href=\"https:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rf-main\">F.46: <code class=\"highlighter-rouge no-highlight\">int<\/code> is the return type for <code class=\"highlighter-rouge no-highlight\">main()<\/code><\/a><\/li>\n<li><a href=\"https:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rf-assignment-op\">F.47: Return <code class=\"highlighter-rouge no-highlight\">T&amp;<\/code> from assignment operators.<\/a><\/li>\n<\/ul>\n<p><strong>Other function rules:<\/strong><\/p>\n<ul>\n<li><a href=\"https:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rf-capture-vs-overload\">F.50: Use a lambda when a function won\u2019t do (to capture local variables, or to write a local function)<\/a><\/li>\n<li><a href=\"https:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rf-default-args\">F.51: Where there is a choice, prefer default arguments over overloading<\/a><\/li>\n<li><a href=\"https:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rf-reference-capture\">F.52: Prefer capturing by reference in lambdas that will be used locally, including passed to algorithms<\/a><\/li>\n<li><a href=\"https:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rf-value-capture\">F.53: Avoid capturing by reference in lambdas that will be used nonlocally, including returned, stored on the heap, or passed to another thread<\/a><\/li>\n<li><a href=\"https:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rf-this-capture\">F.54: If you capture <code class=\"highlighter-rouge no-highlight\">this<\/code>, capture all variables explicitly (no default capture)<\/a><\/li>\n<li><a href=\"https:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#F-varargs\">F.55: Don\u2019t use <code class=\"highlighter-rouge no-highlight\">va_arg<\/code> arguments<\/a><\/li>\n<\/ul>\n<h2><span class=\"ez-toc-section\" id=\"Parameter_passing_semantic_rules\"><\/span>Parameter passing semantic rules:<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>I can make this subsection relatively short. Most of the rules are already explained in the post to the <a href=\"https:\/\/www.modernescpp.com\/index.php\/c-core-guideline-the-guidelines-support-library\">Guideline Support Library<\/a>. So if you are curious, read the cited post. I only want to say a few words to the first rule F.22.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"F22_Use_T_or_owner_to_designate_a_single_object\"><\/span><a href=\"https:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rf-ptr\">F.22: Use <code class=\"highlighter-rouge no-highlight\">T*<\/code> or <code class=\"highlighter-rouge no-highlight\">owner&lt;T*&gt;<\/code> to designate a single object<\/a><span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>&nbsp;What does using T* mean to designate a single object? The rule answers this question. Pointers can be used for many purposes. They can stand for a<\/p>\n<ol>\n<li>single object that this function must not delete<\/li>\n<li>object allocated on the heap that this function must delete<\/li>\n<li>Nullzeiger (<span style=\"font-family: courier new,courier;\">nullptr<\/span>)<\/li>\n<li>C-style string<\/li>\n<li>C-array<\/li>\n<li>location in an array<\/li>\n<\/ol>\n<p>Because of these possibilities, you should use pointers only for single objects (1).<\/p>\n<p>As I mentioned, it will skip the remaining rules F.23 and F.27, regarding function parameters.<\/p>\n<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Value_return_semantic_rules\"><\/span>Value return semantic rules:<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<h3><span class=\"ez-toc-section\" id=\"F42_Return_a_T_to_indicate_a_position_only\"><\/span><a href=\"https:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rf-return-ptr\">F.42: Return a <code class=\"highlighter-rouge no-highlight\">T*<\/code> to indicate a position (only)<\/a><span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>To say it the other way around. You should not use a pointer to transfer ownership. This is a misuse. Here is an 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%;\">Node<span style=\"color: #555555;\">*<\/span> <span style=\"color: #cc00ff;\">find<\/span>(Node<span style=\"color: #555555;\">*<\/span> t, <span style=\"color: #006699; font-weight: bold;\">const<\/span> string<span style=\"color: #555555;\">&amp;<\/span> s)  <span style=\"color: #0099ff; font-style: italic;\">\/\/ find s in a binary tree of Nodes<\/span>\r\n{\r\n    <span style=\"color: #006699; font-weight: bold;\">if<\/span> (t <span style=\"color: #555555;\">==<\/span> nullptr <span style=\"color: #555555;\">||<\/span> t<span style=\"color: #555555;\">-&gt;<\/span>name <span style=\"color: #555555;\">==<\/span> s) <span style=\"color: #006699; font-weight: bold;\">return<\/span> t;\r\n    <span style=\"color: #006699; font-weight: bold;\">if<\/span> ((<span style=\"color: #006699; font-weight: bold;\">auto<\/span> p <span style=\"color: #555555;\">=<\/span> find(t<span style=\"color: #555555;\">-&gt;<\/span>left, s))) <span style=\"color: #006699; font-weight: bold;\">return<\/span> p;\r\n    <span style=\"color: #006699; font-weight: bold;\">if<\/span> ((<span style=\"color: #006699; font-weight: bold;\">auto<\/span> p <span style=\"color: #555555;\">=<\/span> find(t<span style=\"color: #555555;\">-&gt;<\/span>right, s))) <span style=\"color: #006699; font-weight: bold;\">return<\/span> p;\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> nullptr;\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The guidelines are pretty straightforward. You should not return something from a function not in the caller&#8217;s scope. The following rule stresses this point.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"F43_Never_directly_or_indirectly_return_a_pointer_or_a_reference_to_a_local_object\"><\/span><a href=\"https:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rf-dangle\">F.43: Never (directly or indirectly) return a pointer or a reference to a local object<\/a><span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>This rule is obvious but sometimes not so easy to spot if there are a few indirections. The issue starts with the function <span style=\"font-family: courier new,courier;\">f, <\/span>which returns a pointer to a local object.<span style=\"font-family: courier new,courier;\"><br \/><\/span><\/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;\">int<\/span><span style=\"color: #555555;\">*<\/span> <span style=\"color: #cc00ff;\">f<\/span>()\r\n{\r\n    <span style=\"color: #007788; font-weight: bold;\">int<\/span> fx <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">9<\/span>;\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> <span style=\"color: #555555;\">&amp;<\/span>fx;  <span style=\"color: #0099ff; font-style: italic;\">\/\/ BAD<\/span>\r\n}\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">g<\/span>(<span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">*<\/span> p)   <span style=\"color: #0099ff; font-style: italic;\">\/\/ looks innocent enough<\/span>\r\n{\r\n    <span style=\"color: #007788; font-weight: bold;\">int<\/span> gx;\r\n    cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"*p == \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #555555;\">*<\/span>p <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n    <span style=\"color: #555555;\">*<\/span>p <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">999<\/span>;\r\n    cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"gx == \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> gx <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n}\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">h<\/span>()\r\n{\r\n    <span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">*<\/span> p <span style=\"color: #555555;\">=<\/span> f();\r\n    <span style=\"color: #007788; font-weight: bold;\">int<\/span> z <span style=\"color: #555555;\">=<\/span> <span style=\"color: #555555;\">*<\/span>p;  <span style=\"color: #0099ff; font-style: italic;\">\/\/ read from abandoned stack frame (bad)<\/span>\r\n    g(p);        <span style=\"color: #0099ff; font-style: italic;\">\/\/ pass pointer to abandoned stack frame to function (bad)<\/span>\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"F44_Return_a_T_when_the_copy_is_undesirable_and_%E2%80%9Creturning_no_object%E2%80%9D_isnt_an_option\"><\/span><a href=\"https:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rf-return-ref\">F.44: Return a <code class=\"highlighter-rouge no-highlight\">T&amp;<\/code> when the copy is undesirable and \u201creturning no object\u201d isn\u2019t an option<\/a><span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>The C++ language guarantees that a T&amp; always refers to an object. Therefore, the caller must not check for a nullptr because no object isn&#8217;t an option. This rule does not contradict the previous rule F.43 because F.43 states that you should not return a reference to a <strong>local<\/strong> object.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"F45_Dont_return_a_T\"><\/span><a href=\"https:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rf-return-ref-ref\">F.45: Don\u2019t return a <code class=\"highlighter-rouge no-highlight\">T&amp;&amp;<\/code><\/a><span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>With T&amp;&amp;, you are asking to return a reference to a destroyed temporary object. That is extremely bad (F.43).<\/p>\n<p>If the<span style=\"font-family: courier new,courier;\"> f()<\/span> call returns a copy,&nbsp;&nbsp;you will get a reference to a temporary one.<\/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;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">F<\/span><span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">auto<\/span><span style=\"color: #555555;\">&amp;&amp;<\/span> wrapper(F f)\r\n{\r\n    ...\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> f();\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The only exceptions to these rules are <span style=\"font-family: courier new,courier;\">std::move<\/span> for <a href=\"https:\/\/www.modernescpp.com\/index.php\/move-semantic-tow-nice-properties\">move semantic<\/a> and <span style=\"font-family: courier new,courier;\">std::forward<\/span> for <a href=\"https:\/\/www.modernescpp.com\/index.php\/perfect-forwarding\">perfect forwarding<\/a>.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"F46_int_is_the_return_type_for_main\"><\/span><a href=\"https:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rf-main\">F.46: <code class=\"highlighter-rouge no-highlight\">int<\/code> is the return type for <code class=\"highlighter-rouge no-highlight\">main()<\/code><\/a><span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>In standard C++, you can declare <span style=\"font-family: courier new,courier;\">main<\/span> in two ways. <span style=\"font-family: courier new,courier;\">void<\/span> is not C++ and, therefore, limits your portability.<\/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;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>();                      <span style=\"color: #0099ff; font-style: italic;\"> \/\/ C++<\/span>\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>(<span style=\"color: #007788; font-weight: bold;\">int<\/span> argc, <span style=\"color: #007788; font-weight: bold;\">char<\/span><span style=\"color: #555555;\">*<\/span> argv[]); <span style=\"color: #0099ff; font-style: italic;\">\/\/ C++<\/span>\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">main<\/span>();                      <span style=\"color: #0099ff; font-style: italic;\">\/\/ bad, not C++<\/span>\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The second form is equivalent to <code><span class=\"typ\">int<\/span><span class=\"pln\"> main<\/span><span class=\"pun\">(<\/span><span class=\"typ\">int<\/span><span class=\"pln\"> argc<\/span><span class=\"pun\">,<\/span><span class=\"pln\"> <\/span><span class=\"kwd\">char<\/span><span class=\"pun\">**<\/span><span class=\"pln\"> argv<\/span><span class=\"pun\">). <br \/><\/span><\/code><\/p>\n<p>The main function will <span style=\"font-family: courier new,courier;\">return 0;<\/span> implicitly if your main function does not have a return statement.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"F47_Return_T_from_assignment_operators\"><\/span><a href=\"https:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rf-assignment-op\">F.47: Return <code class=\"highlighter-rouge no-highlight\">T&amp;<\/code> from assignment operators.<\/a><span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>The <a href=\"http:\/\/en.cppreference.com\/w\/cpp\/language\/copy_assignment\">copy assignment operator<\/a> should return a T&amp;. Therefore, your type is inconsistent with the standard template library&#8217;s containers and follows the principle: &#8220;do as the ints do&#8221;.<\/p>\n<p>There is a subtle difference between returning by T&amp; or returning by T:<\/p>\n<ol>\n<li><code><span class=\"pln\">A<\/span><span class=\"pun\">&amp;<\/span><span class=\"pln\"> <\/span><span class=\"kwd\">operator<\/span><span class=\"pun\">=(<\/span><span class=\"pln\">constA<\/span><span class=\"pun\">&amp;<\/span><span class=\"pln\"> rhs<\/span><span class=\"pun\">){<\/span><span class=\"pln\"> <\/span><span class=\"pun\">...<\/span><span class=\"pln\"> <\/span><span class=\"pun\">};<br \/><\/span><\/code><\/li>\n<li><code><span class=\"pln\">A<\/span><span class=\"pun\"><\/span><span class=\"pln\"> <\/span><span class=\"kwd\">operator<\/span><span class=\"pun\">=(<\/span><span class=\"pln\">constA<\/span><span class=\"pun\">&amp;<\/span><span class=\"pln\"> rhs<\/span><span class=\"pun\">){<\/span><span class=\"pln\"> <\/span><span class=\"pun\">...<\/span><span class=\"pln\"> <\/span><span class=\"pun\">};<\/span><\/code><\/li>\n<\/ol>\n<p>In the second case, a chain of operations such as<span style=\"font-family: courier new,courier;\"> A a = b = c;<\/span> may result in two additional calls of the copy constructor and of the destructor.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Other_function_rules\"><\/span>Other function rules:<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<h3><span class=\"ez-toc-section\" id=\"F50_Use_a_lambda_when_a_function_wont_do_to_capture_local_variables_or_to_write_a_local_function\"><\/span><a href=\"https:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rf-capture-vs-overload\">F.50: Use a lambda when a function won\u2019t do (to capture local variables, or to write a local function)<\/a><span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>In C++11, we have callables such as functions, function objects, and lambda functions. The question is often: When should you use a&nbsp; function or a lambda function? Here are two simple rules<\/p>\n<ul>\n<li>If your callable has to capture local variables or is declared in a local scope, you have to use a lambda function.<\/li>\n<li>If your callable should support overloading, use a function.<\/li>\n<\/ul>\n<h3><span class=\"ez-toc-section\" id=\"F51_Where_there_is_a_choice_prefer_default_arguments_over_overloading\"><\/span><a href=\"https:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rf-default-args\">F.51: Where there is a choice, prefer default arguments over overloading<\/a><span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>If you need to invoke a function with a different number of arguments, prefer default arguments over overloading. Therefore, you follow the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Don%27t_repeat_yourself\">DRY principle<\/a> (don&#8217;t repeat yourself).<\/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;\">print<\/span>(<span style=\"color: #006699; font-weight: bold;\">const<\/span> string<span style=\"color: #555555;\">&amp;<\/span> s, format f <span style=\"color: #555555;\">=<\/span> {});<span style=\"color: #cc00ff;\"><\/span><span style=\"color: #006699; font-weight: bold;\"><\/span><span style=\"color: #555555;\"><\/span><span style=\"color: #0099ff; font-style: italic;\"><\/span><span style=\"color: #007788; font-weight: bold;\"><\/span><span style=\"color: #cc00ff;\"><\/span><span style=\"color: #006699; font-weight: bold;\"><\/span><span style=\"color: #555555;\"><\/span>\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>versus<\/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;\">print<\/span>(<span style=\"color: #006699; font-weight: bold;\">const<\/span> string<span style=\"color: #555555;\">&amp;<\/span> s);  <span style=\"color: #0099ff; font-style: italic;\">\/\/ use default format<\/span>\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">print<\/span>(<span style=\"color: #006699; font-weight: bold;\">const<\/span> string<span style=\"color: #555555;\">&amp;<\/span> s, format f);\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"F52_Prefer_capturing_by_reference_in_lambdas_that_will_be_used_locally_including_passed_to_algorithms\"><\/span><a href=\"https:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rf-reference-capture\">F.52: Prefer capturing by reference in lambdas that will be used locally, including passed to algorithms<\/a><span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>For performance and correctness reasons, you usually want to capture your variables by reference. For efficiency, that means according to rule<a href=\"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-how-to-pass-function-parameters\"> F.16<\/a>, if your variable p holds: <span style=\"font-family: courier new,courier;\"><\/span><span style=\"font-family: courier new,courier;\">sizeof(p) &gt; 4 * sizeof(int).<\/span><\/p>\n<p>Because you use your lambda function locally, you will not have a lifetime issue with your captured variable <span style=\"font-family: courier new,courier;\">message.<\/span><\/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%;\">std<span style=\"color: #555555;\">::<\/span>for_each(begin(sockets), end(sockets), [<span style=\"color: #555555;\">&amp;<\/span>message](<span style=\"color: #006699; font-weight: bold;\">auto<\/span><span style=\"color: #555555;\">&amp;<\/span> socket)\r\n{\r\n    socket.send(message);\r\n});\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"F53_Avoid_capturing_by_reference_in_lambdas_that_will_be_used_nonlocally_including_returned_stored_on_the_heap_or_passed_to_another_thread\"><\/span><a href=\"https:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rf-value-capture\">F.53: Avoid capturing by reference in lambdas that will be used nonlocally, including returned, stored on the heap, or passed to another thread<\/a><span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>You have to be very careful if you detach a thread. The following code snippet has two<a href=\"https:\/\/www.modernescpp.com\/index.php\/race-condition-versus-data-race\"> race condition<\/a>s.<\/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%;\">std::string s{<span style=\"color: #cc3300;\">\"undefined behaviour\"<\/span>};\r\n<span style=\"color: #006699; font-weight: bold;\">std::thread<\/span> t([<span style=\"color: #555555;\">&amp;<\/span>]{std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> s <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;});\r\nt.detach();\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<ol>\n<li>The thread <span style=\"font-family: courier new,courier;\">t<\/span> may outlive the lifetime of its creator. Hence, <span style=\"font-family: courier new,courier;\">std::string<\/span> does not exist anymore.<\/li>\n<li>The thread <span style=\"font-family: courier new,courier;\">t<\/span> may outlive the lifetime of the main thread. Hence, <span style=\"font-family: courier new,courier;\">std::cout<\/span> does not exist anymore.<\/li>\n<\/ol>\n<h3><span class=\"ez-toc-section\" id=\"F54_If_you_capture_this_capture_all_variables_explicitly_no_default_capture\"><\/span><a href=\"https:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rf-this-capture\">F.54: If you capture <code class=\"highlighter-rouge no-highlight\">this<\/code>, capture all variables explicitly (no default capture)<\/a><span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>If it seems that you use default capture by<span style=\"font-family: courier new,courier;\"> [=]<\/span>, you capture all data members by reference.<\/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;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">My_class<\/span> {\r\n    <span style=\"color: #007788; font-weight: bold;\">int<\/span> x <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">0<\/span>;\r\n\r\n    <span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">f<\/span>() {\r\n        <span style=\"color: #006699; font-weight: bold;\">auto<\/span> lambda <span style=\"color: #555555;\">=<\/span> [<span style=\"color: #555555;\">=<\/span>]{ std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> x; };  <span style=\"color: #0099ff; font-style: italic;\">\/\/ bad  <\/span>\r\n        x <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">42<\/span>;\r\n        lambda();   <span style=\"color: #0099ff; font-style: italic;\">\/\/ 42<\/span>\r\n        x <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">43<\/span>;\r\n        lambda();   <span style=\"color: #0099ff; font-style: italic;\">\/\/ 43<\/span>\r\n    }\r\n};\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The lambda function captures x by reference.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"F55_Dont_use_va_arg_arguments\"><\/span><a href=\"https:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#F-varargs\">F.55: Don\u2019t use <code class=\"highlighter-rouge no-highlight\">va_arg<\/code> arguments<\/a><span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>If you want to pass an arbitrary number of arguments to a function, use variadic templates. In contrast to <span style=\"font-family: courier new,courier;\">va_args<\/span>, the compiler will automatically deduce the correct type. With C++17, we can automatically apply an operator to the arguments.<\/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;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #aa0000; background-color: #ffaaaa;\">...<\/span><span style=\"color: #00aa88; font-weight: bold;\">Args<\/span><span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">auto<\/span> sum(Args... args) { <span style=\"color: #0099ff; font-style: italic;\">\/\/ GOOD, and much more flexible<\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> (... <span style=\"color: #555555;\">+<\/span> args); <span style=\"color: #0099ff; font-style: italic;\">\/\/ note: C++17 \"fold expression\"<\/span>\r\n}\r\n\r\nsum(<span style=\"color: #ff6600;\">3<\/span>, <span style=\"color: #ff6600;\">2<\/span>); <span style=\"color: #0099ff; font-style: italic;\">\/\/ ok: 5<\/span>\r\nsum(<span style=\"color: #ff6600;\">3.14159<\/span>, <span style=\"color: #ff6600;\">2.71828<\/span>); <span style=\"color: #0099ff; font-style: italic;\">\/\/ ok: ~5.85987<\/span>\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>If that looks strange, read my post about<a href=\"https:\/\/www.modernescpp.com\/index.php\/fold-expressions\"> fold expressions<\/a>.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Whats_next\"><\/span>What&#8217;s next?<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Classes are user-defined types. They allow you to encapsulate state and operations. Thanks to class hierarchies, you can organize your types. The <a href=\"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-class-rules\">next post<\/a> will be about the rules for classes and class hierarchies.<\/p>\n<p>&nbsp;<\/p>\n<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Today,&nbsp; I conclude my treatise about the rules for functions in the C++ core guidelines. The last post was about the syntax of function parameters and return values. This post, with its roughly 15 rules, is about their semantics.<\/p>\n","protected":false},"author":21,"featured_media":5288,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[372],"tags":[503],"class_list":["post-5300","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-modern-c","tag-functions"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5300","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=5300"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5300\/revisions"}],"predecessor-version":[{"id":6865,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5300\/revisions\/6865"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5288"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5300"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5300"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5300"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}