Reputation: 366
I've found two ways of using static functions in C.
The first one is:
afile.h
static void afunc(void); // leaving this out gives errors
afile.c
void afunc(void)
{
puts("a");
}
void callafunc(void)
{
afunc();
}
main.c
void afunc(void)
{
puts("b");
}
int main(void)
{
afunc(); // prints b
callafunc(); // prints a
}
The other way is:
afile.h
// declare nothing w.r.t. static functions
afile.c
static void afunc(void)
{
...
}
main.c
static void afunc(void)
{
...
}
Which of these two ways of using static functions is correct?
Upvotes: 4
Views: 221
Reputation: 24796
The point of having header files is the following:
If several translation units (i.e. ".c
files") use the same data types, functions or variables, then the corresponding declarations must appear in every single translation unit. Although the programmer could theoretically write all of these declarations into every .c
file directly, this would make it rather hard for the programmer to change the declarations, because they would have to be changed in every single .c
file. Therefore, it is easier to just make one common header file for several translation units and make the individual translation units #include
the header file using the C preprocessor.
Based on that, what you do in your first example is "correct" in the sense that it will work and it is valid C code. However, it still doesn't make sense, because you are using the same declaration for two unrelated functions.
Even if the functions have the same name and prototype, the functions still are unrelated with each other. This is because the functions have internal linkage (due to the keyword static
).
It does not make sense for unrelated functions to share the same declaration in a header file. For example, if you decide to modify the declaration of one function, how do you want to modify it in your source code? You cannot modify the header file, because then you would also be modifying the other functions with that name in all other translation units.
Therefore, it makes more sense for static
function declarations to be stored inside the .c
file and not inside a common header file.
Upvotes: 2
Reputation: 153458
Which of these two ways of using static functions is correct?
The second method is correct.
static void afunc(void);
is a function declaration. The definition of that function exists somewhere. Since it is also static, if the function is used in this compilation, its definition also needs to be in this compilation of this unit. The function has local linkage.
In the second case, both main.c
and afile.c
use their locally defined afunc(void)
.
There is no need to declare to the global namespace that afunc()
exist. No other compilation unit needs to know about these local functions of main.c, afile.c
The first is usually incorrect.
The first case "worked" because both main.c
and afile.c
use and have a locally defined afunc(void)
.
Should another file foo.c()
, use #include "afile.h"
and try to call afunc()
, it would fail to find a matching local afunc()
unless it too has a locally defined
afunc()
.
"*.h"
is more to tell about the functions, objects, defines, types, etc. that "*.c"
has for the global namespace to use. Such things that are static
are best in top of the "*.c"
for its own use and not in "*.h"
.
The first may be correct in narrow cases.
Example, the "afile.h"
declares and defines a small helper function with the intention that whatever "*.c"
that includes "afile.h"
will get its own local version of afunc()
. By making it static
, these local afunc()
do not collide with a potential global afunc()
or each other.
Upvotes: 4