I would like to know what is the meaning of using static non-member functions in C
and also why one would use those instead of non static ones.
For reference I am reading this question and this question in other site and in there it says
It means that you can't call it from another cpp file
In my situation I have a .h
file and a "main" cpp file.
I have implemented a function in the h file both as a static and non-static non-member one and I can call it from the cpp file and the results don't vary
So I am wondering why and what is the difference or effect of static
Note: Please, this question does not involves static in:
- C
- member functions
- variables
CodePudding user response:
The differences will be seen when linking the whole program and when the functions are called from multiple places.
In case of both foo.cpp
and bar.cpp
including implementation.h
, with static int baz() { return 0; }
, the method baz
will live independently in the compilation units of foo.cpp
and bar.cpp
.
When the method is non-static (and non-inline) the method baz
is considered to be linkable by all compilation units, which know the prototype. In this case compiling gcc foo.cpp bar.cpp
will result in linking error of multiple references for baz
.
CodePudding user response:
In most C implementations, each .cpp
file is compiled into a corresponding .o
file. The .o
file contains the object code for the functions of the .cpp
file -- i.e. the machine-code instructions the CPU will need to execute in order to execute those functions.
For non-static functions, the .o
file also contains linker-readable metadata; i.e. a list of (mangled) function names that are present in the .o
file, where those functions are located within the file, etc. At link-time, the linker will use this metadata to resolve calls to these functions that were made from within other .cpp
files.
For static functions, OTOH, the .o
file does not contain any metadata; as far as the linker is concerned, the static functions do not exist. The static functions are effectively "secret", available only to the other code from the same .cpp
file (which does not depend on the linker to gain access to the static functions as it is compiled as part of the same compilation-unit and can therefore just reference them directly)
In your case you implemented your static function in a .h
file, which means that a separate copy of the function is being included in the .o
file of every .cpp
file that uses that function, which is why it still "works" for you.
People often use static
as a sort of private-namespace marker to guarantee that functions won't be called from outside of the .cpp
file they appear in. In C , an anonymous namespace can be used to achieve a similar result.
CodePudding user response:
As other people explained, in C if your code consist of multiple files, so all the global functions and variables are having external linking
by default. For example a function defined in a file A.cpp
can be called in file B.cpp
by automatic linking by compiler. Remember you have to compile both files separately, and later you will tell the compiler to link these objects .o
files. Compiler will stitch everything together. As I did in the Makefile
below.
But if you want to disable external linking
you will make your function static
so now your function or variable is just available for the file in which it is declared. This is called internal linking
.
Internal linking is used where you have to have global variables, but you do not want that your global variable accessed outside of this file, and some other file modify it accidentally.
For better understanding how does this work play around with this code:
first.cpp
#include <iostream>
/*static*/ void hello(){ //static will not let this code compile
std::cout << "Hello I am external linking" << std::endl;
}
main.cpp
void hello();
int main(){
hello();
}
Makefile
program: first.o main.o
g main.o first.o -o test
main.o: main.cpp
g -g -c main.cpp -o main.o
first.o: first.cpp
g -g -c first.cpp -o first.o
This works as you expected. But if you put static
in the start of hello()
in first.cpp
, this will become internal linking so you will get linking error by the compiler.