The first header file defines a function called ret
with external linkage in every translation unit that includes it. This is incorrect if more than one such TU is linked in the same program.
The second header file defines a function called ret
with internal linkage in every translation unit that includes it. This means that each TU has its own private copy of the function (with a different address) no matter how many are linked together.
There are three correct ways to share code using a header file:
- function with internal linkage (as in your second header, or in C++11 by putting it in a nameless namespace).
- inline function with external linkage (replace
static
with inline
). The meaning of inline
is that although there is only one copy of the function in the program, every TU that uses the function contains its definition.
- declare the function in the header, and define in it exactly one .cpp file (for example ret.cpp).
In C++03 there was a fourth way:
- function with external linkage in a nameless namespace
I believe this is still available in C++11, but in C++11 functions in nameless namespaces have internal linkage by default. I'm not aware of any use in C++11 for making a function in a nameless namespace have external linkage. So as far as functions are concerned, nameless namespaces are a nice way of giving the function internal linkage.
Which one you use depends on your needs. The third option means that you can change the definition of the function without re-compiling the calling code, although you'd still need to re-link the executable unless the function is in a dll.
The first two (static
or inline
) differ in their behaviour if:
- the function contains
static
local variables,
- you compare function pointers to
ret
taken in different TUs,
- you examine your executable size or symbol table,
- the definition of the function is different in different TUs (perhaps due to different #defines), which is forbidden if the function has external linkage but not if internal.
Otherwise they're much the same.
According to the standard, inline
is also a hint that the compiler should optimize calls to that function for fast execution (which in practice means, inline the code at the call site). Most compilers ignore this hint most of the time. They will happily inline a static
but non-inline
function if they assess it to be a good candidate for inlining, and they will happily avoid inlining an inline
function if they assess it to be a bad candidate for inlining.