简体   繁体   中英

What is the reason and the meaning to use static non-member functions in C++?

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

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; } 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 .

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 -- ie 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; ie 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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM