static function in C

What is the point of making a function static in C?


Making a function static hides it from other translation units, which helps provide encapsulation.

helper_file.c

int f1(int);        /* prototype */
static int f2(int); /* prototype */

int f1(int foo) {
    return f2(foo); /* ok, f2 is in the same translation unit */
                    /* (basically same .c file) as f1         */
}

int f2(int foo) {
    return 42 + foo;
}

main.c:

int f1(int); /* prototype */
int f2(int); /* prototype */

int main(void) {
    f1(10); /* ok, f1 is visible to the linker */
    f2(12); /* nope, f2 is not visible to the linker */
    return 0;
}

pmg is spot on about encapsulation; beyond hiding the function from other translation units (or rather, because of it), making functions static can also confer performance benefits in the presence of compiler optimizations.

Because a static function cannot be called from anywhere outside of the current translation unit (unless the code takes a pointer to its address), the compiler controls all the call points into it.

This means that it is free to use a non-standard ABI, inline it entirely, or perform any number of other optimizations that might not be possible for a function with external linkage.


The static keyword in C is used in a compiled file (.c as opposed to .h) so that the function exists only in that file.

Normally, when you create a function, the compiler generates cruft the linker can use to, well, link a function call to that function. If you use the static keyword, other functions within the same file can call this function (because it can be done without resorting to the linker), while the linker has no information letting other files access the function.


Looking at the posts above I would like to give a more clarified answer:

Suppose our main.c file looks like this:

#include "header.h"

int main(void) {
    FunctionInHeader();
}

Now consider three cases:

  • Case 1: Our header.h file looks like this:

     #include <stdio.h>
    
     static void FunctionInHeader();
    
     void FunctionInHeader() {
         printf("Calling function inside header\n");
     }
    

    Then the following command on linux:

     gcc main.c -o main
    

    will succeed! That's because after the main.c file includes the header.h, the static function definition will be in the same main.c file (more precisely, in the same translation unit) to where it's called.

    If one runs ./main, the output will be Calling function inside header, which is what that static function should print.

  • Case 2: Our header header.h looks like this:

      static void FunctionInHeader();     
    

    and we also have one more file header.c, which looks like this:

      #include <stdio.h>
      #include "header.h"
    
      void FunctionInHeader() {
          printf("Calling function inside header\n");
      }
    

    Then the following command

      gcc main.c header.c -o main
    

    will give an error. In this case main.c includes only the declaration of the static function, but the definition is left in another translation unit and the static keyword prevents the code defining a function to be linked

  • Case 3:

    Similar to case 2, except that now our header header.h file is:

      void FunctionInHeader(); // keyword static removed
    

    Then the same command as in case 2 will succeed, and further executing ./main will give the expected result. Here the FunctionInHeader definition is in another translation unit, but the code defining it can be linked.

Thus, to conclude:

static keyword prevents the code defining a function to be linked,
when that function is defined in another translation unit than where it is called.