Search code examples
cfunctionstaticlinkage

Priority of static functions in C


Let's say that you have a file File1.c with a static function Foo and that the function is called within File1.c. Also, in another file (File2.c), you have another Foo function which is not static. I understand that the static function is not visible outside of the file where it is declared and is actually invisible for the linker.

But does that mean that internal calling of Foo function in File1.c is always resolved during compilation?

Are there cases where Foo calling in File1.c can be linked to the global Foo function of File2.c?


Solution

  • does that mean that internal calling of Foo function in File1.c is always resolved during compilation?

    Not necessarily. For the most part, the language itself does not care HOW its rules are enforced, just that they are enforced in the first place.

    We can check how a given toolchain (in my case linux/gcc) chooses to do it with a quick test:

    Starting from a a simple file (test.c):

    #include <stdio.h>
    
    static void foo() {
        printf("hello");
    }
    
    void bar() {
        foo();
    }
    

    And then compile and inspect the resulting object file:

    gcc -c -o test.o test.cpp
    nm test.o
    
    0000000000000018 T bar
    0000000000000000 t foo
                     U _GLOBAL_OFFSET_TABLE_
                     U printf
    

    We see that both foo() and bar() are in the symbol table, but with different flags.

    We can also look at the assembly:

    objdump -d test.o
    
    0000000000000018 <bar>:
      18:   55                      push   %rbp
      19:   48 89 e5                mov    %rsp,%rbp
      1c:   b8 00 00 00 00          mov    $0x0,%eax
      21:   e8 da ff ff ff          callq  0 <foo>
      26:   90                      nop
      27:   5d                      pop    %rbp
      28:   c3                      retq  
    

    And see that the call to foo is yet unlinked (pointing to the 0 placeholder). So we can say with confidence that the resolving can and does happen at link time in this instance.

    Are there cases where Foo calling in File1.c can be linked to the global Foo function of File2.c?

    That's a straight no. It might be possible to make that happen through hacky magic or undefined behavior, but in a normal project, you should be confident it never happens.