I read that
A function with internal linkage is only visible to one compilation unit. (...) A function declared static has internal linkage
For .c
files it sorta makes sense, but I was wondering what happens with static functions in headers, which get included by multiple .c
files but usually have an include guard.
I was reading this answer about static functions in headers, and the first item mentions that it doesn't create a symbol with external linkage and the second item mentions the function is available purely through the header file. Isn't that contradictory? How can the function be available and at the same time have no external symbol? So I did a little test:
/* 1.h */
#ifndef ONE_H
#define ONE_H
#include <stdio.h>
static void foo() {
printf("foo from 1.h %p\n", foo);
return;
}
void bar();
#endif
/* 1.c */
#include "1.h"
#include <stdio.h>
void bar() {
printf("foo,bar from 1.c %p,%p\n", foo, bar);
foo();
}
/* 2.c */
#include "1.h"
#include <stdio.h>
int main() {
printf("foo,bar from main %p,%p\n", foo, bar);
foo();
bar();
return 0;
}
...
debian@pc:~ gcc 2.c 1.c
debian@pc:~ ./a.out
foo,bar from main 0x400506,0x400574
foo from 1.h 0x400506
foo,bar from 1.c 0x400559,0x400574
foo from 1.h 0x400559
As expected bar
is the same across all files, but shouldn't foo
be too? Isn't 1.h
included only once? Adding inline
to foo
resulted in the same behavior. I'm kinda lost.
Read here, how a header file basically works. That should clarify about your actual question.
Briefly: A header file is just inserted instead of the corresponding
#include
directive. So any declarations or definitions are treated by the compiler as if you actually copy/pasted the text into your file.Anyway, you should be careful with function definitions in a header. This is deemed bad style in general. It blows the code for instance, creating redundant copies of that function. Also Function pointers cannot be compared (you never know ...). It is often better to bundle the functions into a library with just the declarations in a header (non-static then: external linkage). There are good justifications sometimes, however (no rule without exceptions). One of them are
inline
functions.