{"id":198,"date":"2011-03-21T00:04:18","date_gmt":"2011-03-21T04:04:18","guid":{"rendered":"http:\/\/adamrosenfield.com\/blog\/?p=198"},"modified":"2011-03-21T00:04:18","modified_gmt":"2011-03-21T04:04:18","slug":"the-tricky-inline-specifier-in-c99","status":"publish","type":"post","link":"http:\/\/adamrosenfield.com\/blog\/2011\/03\/21\/the-tricky-inline-specifier-in-c99\/","title":{"rendered":"The tricky inline specifier in C99"},"content":{"rendered":"<p>Try to compile the following simple C program in C99 mode with GCC:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">inline void foo() {}\r\nint main(void)\r\n{\r\n  foo();\r\n}<\/pre>\n<p>The results may surprise you:<\/p>\n<pre>$ gcc test.c -std=c99\r\n\/tmp\/ccWN4GRh.o: In function `main':\r\ntest.c:(.text+0xa): undefined reference to `foo'\r\ncollect2: ld returned 1 exit status<\/pre>\n<p>Huh?  The function&#8217;s right there!<\/p>\n<p>Well it turns out that this is not a bug in GCC, but a peculiarity in the way the <code>inline<\/code> keyword is defined by the C99 standard.  Basically, a function declared <code>inline<\/code> without either of the <code>extern<\/code> or <code>static<\/code> linkage specifiers only creates an inline definition of that function, <strong>not an external definition<\/strong>.<\/p>\n<p>When presented with a call to such a function, the compiler can choose to call either the inline definition or the external definition.  If it chooses the external definition, and such an external definition doesn&#8217;t exist, we get a linker error, as in the above example.  In the dry words of the standard:<\/p>\n<blockquote><p>ISO\/IEC 9899:1999 \u00a76.7.4\/6:<\/p>\n<p>Any function with internal linkage can be an inline function. For a function with external linkage, the following restrictions apply: If a function is declared with an <strong>inline<\/strong> function specifier, then it shall also be defined in the same translation unit. If all of the file scope declarations for a function in a translation unit include the <strong>inline<\/strong> function specifier without <strong>extern<\/strong>, then the definition in that translation unit is an <em>inline definition<\/em>. An inline definition does not provide an external definition for the function, and does not forbid an external definition in another translation unit. An inline definition provides an alternative to an external definition, which a translator may use to implement any call to the function in the same translation unit. It is unspecified whether a call to the function uses the inline definition or the external definition.<sup>120)<\/sup><\/p><\/blockquote>\n<p>So there are three ways to fix this code:<\/p>\n<ol>\n<li>Give <code>foo<\/code> internal linkage (by declaring it <code>static<\/code>) and avoid the above clause entirely\n<li>Declare <code>foo<\/code> as <code>extern<\/code>\n<li>Provide a separate external definition for <code>foo<\/code> in another translation unit (that is, another source file)\n<\/ol>\n<p>I would strongly recommend against solution #3, since then your code base will have two separate definitions of <code>foo<\/code>, which will be very confusing for people reading your code.  It&#8217;s very easy for them to get out of sync, if somebody changes one definition but forgets to change the other, which makes for some insidious bugs (such as working correctly in a debug build but not in a release build, or vice-versa).<\/p>\n<p>If your inline function is defined and used only in one source file (as in our toy example), solution #1 is the way to go: <a href=\"http:\/\/en.wikipedia.org\/wiki\/Principle_of_least_privilege\">just give it internal linkage<\/a>.  No reason to make it world-accessible.<\/p>\n<p>Conversely, if your inline function is defined in a header file so it can be used throughout your code, it makes more sense to give it external linkage.  Go with solution #2:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">extern inline void foo() { \/* body *\/ }<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Try to compile the following simple C program in C99 mode with GCC: inline void foo() {} int main(void) { foo(); } The results may surprise you: $ gcc test.c -std=c99 \/tmp\/ccWN4GRh.o: In function `main&#8217;: test.c:(.text+0xa): undefined reference to `foo&#8217; collect2: ld returned 1 exit status Huh? The function&#8217;s right there! Well it turns out [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[],"class_list":["post-198","post","type-post","status-publish","format-standard","hentry","category-programming"],"_links":{"self":[{"href":"http:\/\/adamrosenfield.com\/blog\/wp-json\/wp\/v2\/posts\/198","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/adamrosenfield.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/adamrosenfield.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/adamrosenfield.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/adamrosenfield.com\/blog\/wp-json\/wp\/v2\/comments?post=198"}],"version-history":[{"count":4,"href":"http:\/\/adamrosenfield.com\/blog\/wp-json\/wp\/v2\/posts\/198\/revisions"}],"predecessor-version":[{"id":202,"href":"http:\/\/adamrosenfield.com\/blog\/wp-json\/wp\/v2\/posts\/198\/revisions\/202"}],"wp:attachment":[{"href":"http:\/\/adamrosenfield.com\/blog\/wp-json\/wp\/v2\/media?parent=198"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/adamrosenfield.com\/blog\/wp-json\/wp\/v2\/categories?post=198"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/adamrosenfield.com\/blog\/wp-json\/wp\/v2\/tags?post=198"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}