Your problem statement is not very clear. The following program compiles for me:
static void f() { } // <-- your B.cvoid f(); int main() { f(); }
That is the compressed version of what you did (your static function definition resides in B.c which you include, and you have a non-static declaration of the same function).
You can certainly put static function definitions in a header and include that header wherever needed. Of course you duplicate the code; on the other hand you give the compiler a chance to inline the function if it is short.
There is a peculiarity with static functions: Each "incarnation" of a static function has its own set of function-static variables (those which persist across calls).
Here is a somewhat elaborate example of how function-static variables work for static and global functions. It probably looks a bit confusing at first; simply follow the calls though and you'll see what goes on. In particular, the output of static_g()
"static_g(...) called x times" is not monotonous; it starts back at 1 when it is called from a different translation unit because it is essentially a different function. The compiler would not mind if the implementation of static_g()
was different in each translation unit. That becomes clear also when you look at the function address: It is different for each calling translation unit. As the example demonstrates, that is not the case with external functions: There is always only one.