If a function declaration isn't in a header file (.h), but is instead only in a source file (.c), why would you need to use the static keyword? Surely, if you only declare it in a .c file, it isn't seen by other files, as you're not supposed to #include .c files, right?
I have already read quite a few questions and answers about this (eg. here and here), but can't quite get my head around it.
Since static functions have internal linkage we need to define it in every file we include the header file where the function is declared.
A static function in C is a function that has a scope that is limited to its object file. This means that the static function is only visible in its object file. A function can be declared as static function by placing the static keyword before the function name.
Typically, you do not want to place definitions of non-inline functions in header files. If you fail to declare functions that are never called from outside a module as static , code can be adversely affected.
The variables declared in the header files are called static variables. Static variables can be declared in the header files or any other source file. But in the header files, they can only be initialized once while in the source files, they can be initialized any number of times.
What static
does is make it impossible to declare and call a function in other modules, whether through a header file or not.
Recall that header file inclusion in C is just textual substitution:
// bar.c
#include "header.h"
int bar()
{
return foo() + foo();
}
// header.h
int foo(void);
gets preprocessed to become
int foo(void);
int bar()
{
return foo() + foo();
}
In fact, you can do away with header.h
and just write bar.c
this way in the first place. Similarly, the definition for foo
does not need to include the header in either case; including it just adds a check that the definition and declaration for foo
are consistent.
But if you were to change the implementation of foo
to
static int foo()
{
// whatever
return 42;
}
then the declaration of foo
would cease to work, in modules and in header files (since header files just get substituted into modules). Or actually, the declaration still "works", but it stops referring to your foo
function and the linker will complain about that when you try to call foo
.
The main reason to use static
is to prevent linker clashes: even if foo
and bar
were in the same module and nothing outside the module called foo
, if it weren't static
, it would still clash with any other non-static
function called foo
. The second reason is optimization: when a function is static
, the compiler knows exactly which parts of the program call it and with what arguments, so it can perform constant-folding, dead code elimination and/or inlining.
The static
keyword reduces the visibility of a function to the file scope. That means that you can't locally declare the function in other units and use it since the linker does not add it to the global symbol table. This also means that you can use the name in other units too (you may have a static void testOutput();
in every file, that is not possible if the static
is omitted.)
As a rule of thumb you should keep the visibility of symbols as limited es possible. So if you do not need the routine outside (and it is not part of some interface) then keep it static
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With