{"id":103777,"date":"2020-05-21T07:00:00","date_gmt":"2020-05-21T14:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=103777"},"modified":"2020-05-21T07:06:39","modified_gmt":"2020-05-21T14:06:39","slug":"20200521-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20200521-00\/?p=103777","title":{"rendered":"A noinline inline function? What sorcery is this?"},"content":{"rendered":"<p>You can declare a noinline inline function.<\/p>\n<pre>void g();\r\n\r\n\/\/ gcc\r\n__attribute__((noinline)) inline void f()\r\n{\r\n    g();\r\n}\r\n\r\n\/\/ MSVC\r\n__declspec(noinline) inline void f()\r\n{\r\n    g();\r\n}\r\n\r\nvoid tryme()\r\n{\r\n    f();\r\n    f();\r\n}\r\n<\/pre>\n<p>What sorcery is this, a function that is both inline and not-inline?<\/p>\n<p>The two keywords are not contradictory because they describe different senses of the word &#8220;inline&#8221;.<\/p>\n<p>The C++ language keyword <code>inline<\/code> means &#8220;can be defined in multiple translation units without triggering an ODR violation.&#8221; In other words, it lets you put the function definition in a header file that is included by multiple C++ files.<\/p>\n<p>The function attribute\/declaration specifier <code>noinline<\/code> means &#8220;do not inline this function during code generation.&#8221; It is a directive to the optimizer not to perform inline substitution during code generation.<\/p>\n<p>Historically, the <code>inline<\/code> C++ keyword was originally an optimizer hint, but optimizers were given permission to ignore it and make their own decisions about inline substitution during code generation. Nowadays, compilers pretty much ignore the optimization aspect of the <code>inline<\/code> keyword. The only thing that remains of the <code>inline<\/code> keyword is the ability to have multiple definitions without violating ODR.<\/p>\n<p>You could say that the modern sense of the C++ keyword <code>inline<\/code> is &#8220;defined right here.&#8221; It&#8217;s a statement about the source code, not the object code.<\/p>\n<p>In the above example, the function <code>f<\/code> is a noinline inline function. The <code>inline<\/code> keyword allows the definition of <code>f<\/code> to go into a header file that is consumed by multiple translation units. The noinline attribute\/declaration specifier tells the optimizer to emit code for <code>f<\/code> and call it, rather than embedding the body of <code>f<\/code> into its call sites. The function <code>tryme<\/code> will call the function <code>f<\/code> twice, instead of optimizing out the call and just calling <code>g<\/code> twice.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Two different senses of the word inline.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-103777","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Two different senses of the word inline.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/103777","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=103777"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/103777\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=103777"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=103777"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=103777"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}