Search code examples
c++staticlinker-errorsinline-functions

C++ redefinition link error when not using "inline" or "static" keywords with classless functions


So I realize that when including a ".h" file, the compiler essentially copies the contents of that file to the point it was included. So obviously if I had "Utils.h" included in many files, if utils.h holds a functions implementation, it would cause the redefinition error.

I also realize using the inline keyword fixes this problem by essentially eliminating the function and in-lining it at its usage sites.

Now my question is, when the static keyword is used in the header file, it also seems to fix the problem, but I'm not sure I quite understand why/how it fixes the problem...? It's my understanding that static in a cpp file would essentially make it only available in that compilation unit.

To make sure we're all on the same page here is a snippet of the code in question:

//Utils.h (included in many places)
namespace utils {

    void someUtil() {
        //do work
    }

}

where the above would throw the error, but with static and/or inline keyword, there would be no issue.

So I'm wanting to know what static is doing in this case, and should I use that as well as inline if its a small function body or...?


Solution

  • static, tells the compiler to generate the function in every translation unit where it is defined, and just not share it. So you end up with an arbitrary number of technically separate functions existing in the resulting executable if you use in many translation units and if you check the address of the function in different TUs you will have different results.

    inline function on the other hand:

    There may be more than one definition of an inline function or variable (since C++17) in the program as long as each definition appears in a different translation unit and (for non-static inline functions and variables (since C++17)) all definitions are identical. For example, an inline function or an inline variable (since C++17) may be defined in a header file that is #include'd in multiple source files.

    So The compiler will then either inline calls to the function, or merge together the function definitions from different TU's (so that the resulting function exists once in the executable).

    so in your case inline is what you need.