C++ extern keyword on functions. Why no just include the header file?

前端 未结 5 1721
无人及你
无人及你 2020-12-12 16:13

If I understand it correctly this means

extern void foo();

that the function foo is declared in another translation unit.

1) Why no

相关标签:
5条回答
  • 2020-12-12 16:50

    As others have already stated, the extern keyword is used to state the name (a variable or function) has external linkage, meaning the name refers to the same object in the entire program. Also, this is the default for variables and functions defined at the file scope, so this usage is superfluous.

    There's another use of the extern keyword that goes like this:

    extern "C" void foo();
    

    This means the function foo will be linked using the C conventions for linkage (maybe because this is a function defined in a C library or is a function intended to be called by C programs).

    0 讨论(0)
  • 2020-12-12 16:57

    1) I don't know why I'd need this for a function. Maybe someone else can step in.

    2) The linker determines this by going through all object files and checking the symbols inside each object file. I assume that depending on your linker, the exact search order might vary.

    For GNU binutils' ld all object files and libraries that appear in the linker command line after the object containing the missing symbol are searched from left to right and the first found symbol is picked.

    Example 1:

    • a.o -- uses foo(), bar()
    • liba -- provides bar()
    • libb -- provides foo()

    $> ld a.o -la -lb

    will result in a.o being searched for undefined symbols. Thereafter ld will go through the libs from left to right to search for these symbols and will find bar in liba and foo in libb.

    This may lead to strange problems upon circular dependencies:

    Example 2:

    • a.o -- uses bar()
    • liba -- provides bar(), uses foo()
    • libb -- provides foo(), uses bar()

    Now, there is a circular dependency between liba and libb and linking will fail:

    $> ld a.o -la -lb

    because when searching through the undefined symbols in libb, ld will determine that there is no other lib to the right of -lb that provides this symbol. This may be fixed in at least two ways:

    1) link liba twice: $> ld a.o -la -lb -la

    2) use ld's grouping feature $> ld a.o --start-group -la -lb --end-group

    In case 2), the grouping tells ld to search through all symbols in all libs belonging to this group.

    0 讨论(0)
  • 2020-12-12 16:59

    No, this means that function foo is declared with external linkage. External linkage means that name foo refers to the same function in the entire program. Where the function is defined does not matter. It can be defined in this translation unit. It can be defined in other translation unit.

    Using extern keyword as shown in your example is superfluous. Functions always have external linkage by default. The above is 100% equivalent to just

    void foo();
    

    As for the linker, when the linker links the program together it simply looks everywhere. It looks through all definitions until it finds the definition for foo.

    0 讨论(0)
  • 2020-12-12 17:02

    1) It may not have a header file. But yes, in general, for large projects, you should have a header file if multiple translation units are going to use that function (don't repeat yourself).

    2) The linker searches through all the object files and libraries it was told about to find functions and other symbols.

    0 讨论(0)
  • 2020-12-12 17:07

    It already means that without the extern keyword. Functions have external linkage by default, unless you declare them static.

    Using function prototypes is okay but it is easy get it wrong. The linker error you'll get isn't that easy to diagnose when you redefine the function implementation. The linker doesn't know where to look, it is your job to give it an object file that contains the function definition to keep it happy.

    0 讨论(0)
提交回复
热议问题