{"id":5021,"date":"2016-11-07T16:10:16","date_gmt":"2016-11-07T16:10:16","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/inline\/"},"modified":"2023-06-26T12:36:52","modified_gmt":"2023-06-26T12:36:52","slug":"inline","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/inline\/","title":{"rendered":"inline"},"content":{"rendered":"<p>Thanks to <span style=\"font-family: courier new,courier;\">inline<\/span>, the compiler can replace the function call with the function body. There are two reasons to use <span style=\"font-family: courier new,courier;\">inline<\/span> functions: performance and safety.<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<\/p>\n<p>My primary goal was to write this post about performance. Fortunately, a further significant benefit of inline came to my mind. <span style=\"font-family: courier new,courier;\">inline<\/span> makes macros a function replacement superfluous.<\/p>\n<h2>Macro must go<\/h2>\n<p>Macros are only the poor man&#8217;s means to replace text. Macros have no understanding of the C++ syntax. Therefore, a lot can go wrong.<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"> 1\r\n 2\r\n 3\r\n 4\r\n 5\r\n 6\r\n 7\r\n 8\r\n 9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21\r\n22\r\n23\r\n24\r\n25\r\n26\r\n27\r\n28\r\n29\r\n30\r\n31\r\n32\r\n33\r\n34\r\n35<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008000;\">\/\/ macro.cpp<\/span>\r\n\r\n<span style=\"color: #0000ff;\">#include &lt;iostream&gt;<\/span>\r\n\r\n<span style=\"color: #0000ff;\">#define  absMacro(i) ( (i) &gt;= 0 ? (i) : -(i) )<\/span>\r\n\r\n<span style=\"color: #0000ff;\">inline<\/span> <span style=\"color: #2b91af;\">int<\/span> absFunction(<span style=\"color: #2b91af;\">int<\/span> i){\r\n  <span style=\"color: #0000ff;\">return<\/span> i &gt;= 0 ? i : -i;\r\n}\r\n\r\n<span style=\"color: #2b91af;\">int<\/span> func(){ \r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"func called\"<\/span> &lt;&lt; std::endl;\r\n  <span style=\"color: #0000ff;\">return<\/span> 0;\r\n}\r\n\r\n\r\n<span style=\"color: #2b91af;\">int<\/span> main(){\r\n  \r\n  std::cout &lt;&lt; std::endl;\r\n  \r\n  <span style=\"color: #0000ff;\">auto<\/span> i(0);\r\n  <span style=\"color: #0000ff;\">auto<\/span> res = absMacro(++i);   \r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"res: \"<\/span> &lt;&lt; res &lt;&lt; std::endl;\r\n  absMacro(func());\r\n  \r\n  std::cout &lt;&lt; std::endl;\r\n  \r\n  i=0;\r\n  res= absFunction(++i);     \r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"res: \"<\/span> &lt;&lt; res &lt;&lt; std::endl;\r\n  absFunction(func());\r\n  \r\n  std::cout &lt;&lt; std::endl;\r\n  \r\n}\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5020\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/inline.png\" alt=\"inline\" width=\"344\" height=\"261\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/inline.png 344w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/inline-300x228.png 300w\" sizes=\"auto, (max-width: 344px) 100vw, 344px\" \/><\/p>\n<p>The macro in line 5, as the <span style=\"font-family: courier new,courier;\">inline<\/span> function in lines 7 &#8211; 9, returns the absolute value of its arguments. I invoke the function with the argument <span style=\"font-family: courier new,courier;\">++i. i<\/span> is 0. The result should be 1. It should be&nbsp;because the macro increments the expression <span style=\"font-family: courier new,courier;\">i<\/span> two times. Consequently, the result is <span style=\"font-family: courier new,courier;\">2<\/span> instead of <span style=\"font-family: courier new,courier;\">1.<\/span> The function <span style=\"font-family: courier new,courier;\">func<\/span> shows it explicitly. When I use the function <span style=\"font-family: courier new,courier;\">func<\/span> as an argument, the function will be invoked two times in the case of the macro but only once in the case of the <span style=\"font-family: courier new,courier;\">inline<\/span> function.<\/p>\n<p>What&#8217;s happening if I use an <span style=\"font-family: courier new,courier;\">inline<\/span> function?<\/p>\n<\/p>\n<h2>inline<\/h2>\n<p>At first, all behave not as it seems. The compiler will interpret it only as a recommendation if I declare a function as inline. The compiler is free to ignore my recommendation. But it will also work the other way around. Modern compilers like Microsoft Visual C++, gcc, or clang can <span style=\"font-family: courier new,courier;\">inline<\/span> a function if it makes sense from a performance perspective.<\/p>\n<p>Now I have to write in the conjunctive. We must assume the compiler will accept my recommendation and apply the inline keyword in the <span style=\"font-family: courier new,courier;\">exchange<\/span> function.<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0000ff;\">inline<\/span> <span style=\"color: #2b91af;\">void<\/span> exchange(<span style=\"color: #2b91af;\">int<\/span>&amp; x, <span style=\"color: #2b91af;\">int<\/span>&amp; y){\r\n  <span style=\"color: #2b91af;\">int<\/span> temp= x;\r\n  x= y;\r\n  y= temp;\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>What&#8217;s happening at the function invocation?<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\">...\r\n<span style=\"color: #0000ff;\">auto<\/span> a(2011);\r\n<span style=\"color: #0000ff;\">auto<\/span> b(2014);\r\nexchange(a,b);\r\n...\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The compiler substitutes the function call by the function body.<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\">...\r\n<span style=\"color: #0000ff;\">auto<\/span> a(2011);\r\n<span style=\"color: #0000ff;\">auto<\/span> b(2014);\r\n<span style=\"color: #2b91af;\">int<\/span> temp= a;\r\na= b;\r\nb= temp;\r\n...\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The small example shows the advantages and disadvantages of inline a function.<\/p>\n<h3>Advantages<\/h3>\n<ul>\n<li>No function call is necessary.<\/li>\n<li>Variables have not to be pushed onto or removed from the function stack.<\/li>\n<li>The function needs no return value.<\/li>\n<li>The<a href=\"https:\/\/en.wikipedia.org\/wiki\/CPU_cache\"> instruction cache<\/a> can&nbsp;be used optimally. New instructions don&#8217;t have to be loaded but can be immediately performed.<\/li>\n<\/ul>\n<h3>Disadvantages<\/h3>\n<ul>\n<li>The size of the executable grows.<\/li>\n<\/ul>\n<p>Although I only mentioned one disadvantage that should not be judged. The usage of the keyword inline is a balance between performance versus the size of the executable. That was the simple rule. The details are a lot more complicated. Using inline, the executable may become faster or slower, bigger or smaller<span style=\"font-family: courier new,courier;\">. inline <\/span>can cause or prevent the crash of your program. <span style=\"font-family: courier new,courier;\">inline<\/span> case increases or decreases the number of <a href=\"https:\/\/en.wikipedia.org\/wiki\/CPU_cache\">cache misses<\/a> of your program. Those who want to be confused should read the FAQ about <span style=\"font-family: courier new,courier;\">inline<\/span> functions at <a href=\"https:\/\/isocpp.org\/wiki\/faq\/inline-functions\">isocpp.org<\/a>.<\/p>\n<p>Until this point, I only wrote about functions. Of course, you can also declare methods as <span style=\"font-family: courier new,courier;\">inline.<\/span><\/p>\n<h2>inline methods<\/h2>\n<p>A method can become implicitly and explicitly inline implicitly if you define the method in the class body explicitly if you define the methods outside the class body and use the keyword <span style=\"font-family: courier new,courier;\">inline.<\/span><\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<p>&nbsp;<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"> 1\r\n 2\r\n 3\r\n 4\r\n 5\r\n 6\r\n 7\r\n 8\r\n 9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008000;\">\/\/ inline.cpp<\/span>\r\n\r\n<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">MyClass<\/span>{\r\npublic:\r\n  <span style=\"color: #2b91af;\">void<\/span> implicitInline(){};\r\n  <span style=\"color: #2b91af;\">void<\/span> explicitInline();\r\n  <span style=\"color: #0000ff;\">inline<\/span> <span style=\"color: #2b91af;\">void<\/span> notInline();\r\n};\r\n\r\n<span style=\"color: #0000ff;\">inline<\/span> <span style=\"color: #2b91af;\">void<\/span> MyClass::explicitInline(){}\r\n<span style=\"color: #2b91af;\">void<\/span> MyClass::notInline(){}\r\n\r\n<span style=\"color: #2b91af;\">int<\/span> main(){\r\n\r\n  MyClass cl;\r\n  cl.implicitInline();\r\n  cl.explicitInline();\r\n  cl.notInline();\r\n\r\n}\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Therefore, the method <span style=\"font-family: courier new,courier;\">implicitInline<\/span> (line 5) is <span style=\"font-family: courier new,courier;\">inline<\/span> because I defined it in the class boy. Therefore, the method <span style=\"font-family: courier new,courier;\">explicitInline<\/span> (line 6) is <span style=\"font-family: courier new,courier;\">inline<\/span> because I used the keyword <span style=\"font-family: courier new,courier;\">inline<\/span> at the point of the method definition. I want to stress one point. If I use only the keyword <span style=\"font-family: courier new,courier;\">inline<\/span> at the point of the <strong>method declaration,<\/strong> I will not get an inline function. This error happened to me with the method <span style=\"font-family: courier new,courier;\">notInline<\/span> (line 7).<\/p>\n<h2>General recommendation<\/h2>\n<p>Good advice is expensive. Should you use the keyword <span style=\"font-family: courier new,courier;\">inline<\/span> ever or never? Of course, the answer is not so simple. You should use inline if you have a function that is time critical and you invoke this function not too often. In this case, the performance advantages will dominate the size disadvantages.<\/p>\n<p>But we have to keep the big picture in our mind. The&nbsp;Working Group WG 21 wrote the paper <a href=\"http:\/\/www.open-std.org\/jtc1\/sc22\/wg21\/docs\/TR18015.pdf\">ISO\/IEC TR 18015<\/a> about C++ performance in 2006.&nbsp; Chapter 5.3.4 of the paper explicitly discusses the keyword <span style=\"font-family: courier new,courier;\">inline<\/span> on five popular C++ compilers. They compare in this chapter functions, <span style=\"font-family: courier new,courier;\">inline<\/span> functions, and macros.&nbsp; The conclusion in the paper is that inline function calls are about 2-17 times faster than function calls and that inline function calls and macros are in the same performance range.&nbsp;<\/p>\n<p><strong>If this rule of thumb is too simple for you, you should measure the performance of your program. This is, in particular, true for embedded systems that have more substantial resource concerns. <\/strong><\/p>\n<p>&nbsp;<\/p>\n<p><em>After getting much attention at <a href=\"https:\/\/www.reddit.com\/r\/cpp\/comments\/5c1dbt\/inline\/\">Reddit <\/a>for missing the main point about inline functions I will add a few words about ODR.<\/em><\/p>\n<h2>ODR<\/h2>\n<p>ODR stands for the One Definition Rule and says in the case of a function.<\/p>\n<ul>\n<li>A function can have not more than one definition in any translation unit.<\/li>\n<li>A function can have not more than one definition in the program.<\/li>\n<li><strong>Inline functions<\/strong> with external linkage can be defined in more than one translation. The definitions must satisfy the requirement that each must be the same.<\/li>\n<\/ul>\n<p>In modern compilers, the keyword <span style=\"font-family: courier new,courier;\">inline<\/span> is not about inlining functions anymore. Modern compilers almost completely ignore it. The more or less use-case for <span style=\"font-family: courier new,courier;\">inline<\/span> is to mark functions for ODR correctness. In my opinion, the name <span style=\"font-family: courier new,courier;\">inline<\/span> is nowadays quite misleading.&nbsp;<\/p>\n<h3>C versus C++<\/h3>\n<p>Sorry, the confusion will not end here. I want to stress that point explicitly<span style=\"font-family: courier new,courier;\">.inline<\/span> function by default has <strong>external linkage<\/strong> in C++. This is different from C. In C, <span style=\"font-family: courier new,courier;\">inline<\/span> functions, by default, have <strong>internal linkage<\/strong>. You can read the details in the article <a href=\"http:\/\/www.ibm.com\/support\/knowledgecenter\/ssw_ibm_i_72\/rzarg\/inline_linkage.htm\">Linkage of inline functions.<\/a><\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>This was a post about classical C++. In the next post, I will write about C++11. C++11 has the keyword <span style=\"font-family: courier new,courier;\">constexpr<\/span>. You can use <span style=\"font-family: courier new,courier;\">constexpr<\/span> for values, functions, and user-defined data types. By <span style=\"font-family: courier new,courier;\">constexpr<\/span> declared constant expression can be evaluated at compile time. They offer a lot of benefits. Which? You will see it in the <a href=\"https:\/\/www.modernescpp.com\/index.php\/constant-expressions-with-constexpr\">next post.<\/a><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Thanks to inline, the compiler can replace the function call with the function body. There are two reasons to use inline functions: performance and safety.<\/p>\n","protected":false},"author":21,"featured_media":5020,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[364],"tags":[513],"class_list":["post-5021","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-embedded","tag-inline"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5021","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=5021"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5021\/revisions"}],"predecessor-version":[{"id":6928,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5021\/revisions\/6928"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5020"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5021"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5021"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5021"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}