How does extern inline declaration cause code generation?


I'm quoting these lines from this link: Is "inline" without "static" or "extern" ever useful in C99?

To make inline work in c99 we need to do the following:


non-extern "inline" <em>definition</em> goes in the header (but does not necessarily result in any code generation at all), while the "extern inline" <em>declaration</em> goes in the .c file and actually causes the code to be generated.


The above behaviour has been questioned about but there is no answer I could find.

It just seems the C designer were high at the time. How does the above rule work? In every other C style coding definition goes in header and declaration goes in source file. But here it's backward and a declaration causes code generation?


You're saying that "function definitions should go to translation units"... yes, but an inline function is such that it is supposed to be inlinable in another translation unit. And the C compilers commonly do not look for code to inline from other translation units, but they just compile separate translation units into separate object files and only the linker would see the program in its entirety.

Back in times the solution for this would be to define a function in a header file with static (note it is a definition in a header file!), and <em>hope</em> that the compiler would be smart enough to inline the function. But a stupid compiler would generate a separate static function in each translation unit, and not inline anything, leading to both bad performance and wasted memory.

Now with inline and extern inline it means that a function defined as inline foo is supposed to be the <em>same</em> function throughout the program - you can take the function pointer of it in any translation unit and you will get the same function pointer.

Anywhere you see inline void foo(int bar) { ... } it is equally a function definition. But only in one translation unit in the entire program would there be extern inline void foo(int bar); that would cause the function with <em>external</em> linkage to appear in that file. This has a nice property in that it makes legacy tool chains (linkers etc) be able to completely ignore the inline keyword behaviour, they just see that there is one symbol foo for a function in that one object file.

Finally, you're not required to have the same function definition as the externally defined one - it can be a different one - just do not include the inline function definition from the header but define a completely <em>different</em> one, for example

inline int foo(void) { puts("Hello from an inlined function"); } extern inline int foo(void) { puts("Hello from an external function using a completely different algorithm" " here that results in more code bloat but offsets the fact that the" " function call to this definition was not inlined"); }

But it is nice that the C allows you to have the same definition without repeating yourself!


It might be clearer to say the extern declaration triggers generation of an external definition of the function rather than that it causes code to be generated.

As long as all of the declarations of a function in a translation unit are inline without extern, the compiler just provides inline implementations, per C 2018 6.7.4 7:


… If all of the file scope declarations for a function in a translation unit include the inline function specifier without extern, 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,…


So, when you add an extern declaration, the condition in that rule is no longer satisfied—it is no longer true that there are only inline declarations without extern. That cues the compiler to include an external non-inline implementation in the code it generates.



  • How to concatenate unique values in column B by singular values in column A
  • How to add a height/width constraint with iOS Designer in Xamarin Studio?
  • How to move model to the other section in Django's site admin
  • Final managed exception handler in a mixed native/managed executable?
  • RSA and AES encryption
  • Haskell type length + 1
  • Find out the size of a polymorphic object
  • Precompile asp.net views with ms build
  • Custom property attributes in Objective-c
  • How to do the disintegration animation when clicking on Thanos' gauntlet when searching THANOS
  • Have I implemented EpicPandaForce's RealmManager correctly?
  • insert into where not exists in hive
  • Jquery's Ajax Property For Asp.Net 2.0
  • placeholder works for text but not password box in IE/Firefox using this javascript
  • How can I achieve this Many-to-many relationship in Firebase?
  • What is wrong with my use of XPath in C#?
  • React Native 'require' gotcha? Works for local image file, but not csv file in same direct
  • Is MulticastSocket supported in Android 2.3?
  • Turning an array of jquery objects into html
  • How can I encrypt, decrypt and sign using .pfx certificate?
  • search the database based on the value selected from database
  • .Net how to set IsReadOnly for a property for a usercontrol
  • Encode string to Base64 in Inno Setup (Unicode Version of Inno Setup)
  • device tree overlay phandle
  • Arc gradients in Flutter?
  • Calling a flash ExternalInterface in swiffyobject
  • Facebook friend list in Facebook Android SDK 3.14
  • Unable to run testNG tests from maven
  • playing mp3 from nsbundle
  • How to define something in JavaScript [closed]
  • How to write seo friendly url's using htaccess?
  • Django, uWSGI & nginx: Process dies for “no reason”
  • using maven pom while creating jar:test-jar some times it says JAR will be empty - no content was ma
  • Why is ordered choice in pyparsing failing for my use case?
  • Python 3x- Compression Makes File Bigger :(
  • Amazon Elastick BeanStalk error: Failed to create the AWS Elastic Beanstalk application version
  • How to decleare char *const argv[] in swift [duplicate]
  • Apple Mach-O Linker error (“duplicate symbol”)
  • Grails - How to implement a foreign key relationship not using an id column?
  • Using Service Component Runtime