在 C 和 C++ 中,链接器如何找到包含已实现函数的正确文件?

In C and C++, how does the linker find the right file with the implemented functions?

这是我在 C 中的代码。我习惯了 Java,因此我不明白 C 编译器如何使用实现的方法找到正确的源文件。

例如,如果我将 sample_c1.cpp 文件与 Main.cpp 放在一起,它将转到 sample_c1.cpp 的 on_start()。如果我删除 sample_c1.cpp 并将 sample_c2.cpp 与 Main.c 放在一起,它将转到 sample_c2.cpp.

的 on_start()

这是我的测试程序:

Main.c

//no includes to sample_c1.cpp or sample_c2.cpp

void on_start();
void on_stop();
int main(int argc, char* argv[]){

    on_start();
    return 0;
}

sample_c1.cpp

//this is all i have in the file no class definition no nothing just implementations of the methods 
void on_start(){
    ....
}

void on_stop(){
    ......
}

sample_c2.cpp

//this is all i have in the file no class definition no nothing just implementations of the methods 
void on_start(){
    ....
}

void on_stop(){
    ......
}

一般来说,使用具有外部链接的符号的多个定义来编译程序会导致未定义的行为。

实际上,当您这样做时,链接器通常会抛出错误。

您的 IDE 告诉编译器*您项目中所有源文件的名称。编译器*一次处理它们。如果它发现您正在调用一个未在同一源文件中定义的函数,那么它将在其他源文件中查找。如果您有一个名为 sample_c1.cpp 的文件,那么它会在那里查找。如果您有一个名为 sample_c2.cpp 的文件,那么它会在那里查找。如果您有一个名为 travel_back_in_time_and_murder_hitler.cpp 的文件,那么它将在那里查找。

真的没有什么令人兴奋的事情发生。 Java 中没有 "classpath"。只是一堆制作程序的源文件。

* 实际上是链接器,但是编译器和链接器之间的区别超出了这个问题的范围。它基本上只是编译器的另一部分。