The question was about plain c functions, not c++ static
methods, as clarified in comments.
Ok, I understand what a static
variable is, but what is a static
function?
And why is it that if I declare a function, let's say void print_matrix
, in let's say a.c
(WITHOUT a.h
) and include "a.c"
- I get "print_matrix@@....) already defined in a.obj"
, BUT if I declare it as static void print_matrix
then it compiles?
UPDATE Just to clear things up - I know that including .c
is bad, as many of you pointed out. I just do it to temporarily clear space in main.c
until I have a better idea of how to group all those functions into proper .h
and .c
files. Just a temporary, quick solution.
There is a big difference between static functions in C and static member functions in C++. In C, a static function is not visible outside of its translation unit, which is the object file it is compiled into. In other words, making a function static limits its scope. You can think of a static function as being "private" to its *.c file (although that is not strictly correct).
In C++, "static" can also apply to member functions and data members of classes. A static data member is also called a "class variable", while a non-static data member is an "instance variable". This is Smalltalk terminology. This means that there is only one copy of a static data member shared by all objects of a class, while each object has its own copy of a non-static data member. So a static data member is essentially a global variable, that is a member of a class.
Non-static member functions can access all data members of the class: static and non-static. Static member functions can only operate on the static data members.
One way to think about this is that in C++ static data members and static member functions do not belong to any object, but to the entire class.
Minimal runnable multi-file scope example
Here I illustrate how
static
affects the scope of function definitions across multiple files.a.c
main.c
Compile
Output
Interpretation
sf
, one for each filef
As usual, the smaller the scope, the better, so always declare functions
static
if you can.In C programming, files are often used to represent "classes", and
static
functions represent "private" methods of the class.A common C pattern is to pass a
this
struct around as the first "method" argument, which is basically what C++ does under the hood.What standards say about it
C99 N1256 draft 6.7.1 "Storage-class specifiers" says that
static
is a "storage-class specifier".6.2.2/3 "Linkages of identifiers" says
static
impliesinternal linkage
:and 6.2.2/2 says that
internal linkage
behaves like in our example:where "translation unit" is a source file after preprocessing.
How GCC implements it for ELF (Linux)?
With the
STB_LOCAL
binding.If we compile:
and disassemble the symbol table with:
the output contains:
so the binding is the only significant difference between them.
Value
is just their offset into the.bss
section, so we expect it to differ.STB_LOCAL
is documented on the ELF spec at http://www.sco.com/developers/gabi/2003-12-17/ch4.symtab.html:which makes it a perfect choice to represent
static
.Functions without static are
STB_GLOBAL
, and the spec says:which is coherent with the link errors on multiple non static definitions.
If we crank up the optimization with
-O3
, thesf
symbol is removed entirely from the symbol table: it cannot be used from outside anyways. TODO why keep static functions on the symbol table at all when there is no optimization? Can they be used for anything?See also
extern
is the opposite ofstatic
, and functions are alreadyextern
by default: How do I use extern to share variables between source files?Try it yourself
Example on GitHub for you to play with.
static
functions are functions that are only visible to other functions in the same file (more precisely the same translation unit).EDIT: For those who thought, that the author of the questions meant a 'class method': As the question is tagged
C
he means a plain old C function. For (C++/Java/...) class methods,static
means that this method can be called on the class itself, no instance of that class necessary.There are two uses for the keyword static when it comes to functions in C++.
The first is to mark the function as having internal linkage so it cannot be referenced in other translation units. This usage is deprecated in C++. Unnamed namespaces are preferred for this usage.
The second usage is in the context of a class. If a class has a static member function, that means the function is a member of the class (and has the usual access to other members), but it doesn't need to be invoked through a particular object. In other words, inside that function, there is no "this" pointer.
First: It's generally a bad idea to include a
.cpp
file in another file - it leads to problems like this :-) The normal way is to create separate compilation units, and add a header file for the included file.Secondly:
C++ has some confusing terminology here - I didn't know about it until pointed out in comments.
a)
static functions
- inherited from C, and what you are talking about here. Outside any class. A static function means that it isn't visible outside the current compilation unit - so in your case a.obj has a copy and your other code has an independent copy. (Bloating the final executable with multiple copies of the code).b)
static member function
- what Object Orientation terms a static method. Lives inside a class. You call this with the class rather than through an object instance.These two different static function definitions are completely different. Be careful - here be dragons.
static function definitions will mark this symbol as internal. So it will not be visible for linking from outside, but only to functions in the same compilation unit, usually the same file.