C++ C/C++;功能-如何允许原型?

C++ C/C++;功能-如何允许原型?,c++,c,function,compiler-construction,prototype,C++,C,Function,Compiler Construction,Prototype,标题 假设(因为,作为初学者,我不确定)编译器从上到下读取源代码。如果在主函数中调用一个函数时,还没有定义所调用的函数,编译器如何理解应该执行哪些操作 谢谢。打个比方:如果你把车开进修理厂,你需要详细了解修理工诊断和修理问题的全部程序吗?不,你所需要的只是有关你将如何与修理店互动的信息:你需要开车进进出出,你应该向他们付款,他们可能会提供往返你工作地点的免费班车,等等 以类似的方式,C/C++编译器能够生成机器代码,将程序执行的控制权从一个函数转移到另一个函数,然后在调用的函数完成后,在停止的地

标题


假设(因为,作为初学者,我不确定)编译器从上到下读取源代码。如果在主函数中调用一个函数时,还没有定义所调用的函数,编译器如何理解应该执行哪些操作


谢谢。

打个比方:如果你把车开进修理厂,你需要详细了解修理工诊断和修理问题的全部程序吗?不,你所需要的只是有关你将如何与修理店互动的信息:你需要开车进进出出,你应该向他们付款,他们可能会提供往返你工作地点的免费班车,等等

以类似的方式,C/C++编译器能够生成机器代码,将程序执行的控制权从一个函数转移到另一个函数,然后在调用的函数完成后,在停止的地方继续执行原始函数。它需要知道的只是被调用函数的接口(通过原型指定),而不是它所做的全部细节


(当然,如果编译器确实知道被调用函数的定义,那么它可以选择在此基础上执行一些优化,直到“内联”类似地,如果你对汽车修理有一点了解,你也许可以自己修理一些简单的问题,而不是把它交给机械师。)

在大多数架构上,调用函数所需的汇编指令只取决于该函数的参数数量和类型,而不是函数本身是如何实现的。换句话说,按该顺序调用任何接受int和double的函数都需要完全相同的汇编指令序列

当编译器读取函数原型时,它通常不会生成任何代码,而只是在心里记下这样一句话:“好的,当我看到有人从现在开始调用这个函数时,我会知道函数所期望的参数的数量和类型,这样我就可以生成正确的代码。”例如,如果它看到了原型

 void doTheThing(int, double);
当它看到呼叫时

double x, y;
doTheThing(x, y);
它可以生成计算x的代码,将其缩小为整数,然后(通过某种机制)将x和y的值作为参数存储到函数中,调用函数,然后清除参数。它之所以知道将x转换为int是因为它看到了原型,并且基于架构的工作方式,它可以设置调用函数的机制


换句话说,原型本身不生成任何代码。相反,它会通知编译器以后如何生成代码,以便发送参数,并以正确的形式和顺序提取返回值。

无可否认,问题之间有一点差异(在同一个/其他文件中定义的函数),但两人都在问编译器如何在没有看到函数定义的情况下使用函数。看看这篇文章,这应该是它的一个副本,并把它作为一个隐喻:链接器确保我在文章中提到的麻烦不会发生?它实际上是否重新定位了代码中的内容,以便编译器可以从上到下读取?如果我没有正确理解,你能解释一下,或者让我试着从论坛上得到答案吗?不,正如dupe中所解释的,编译器首先不需要知道函数的作用是什么。它只需要知道接受什么参数和返回什么。但我想可能还有更好的方法。要调用一个函数,只需要它的地址——一条信息。(原型只是一种安全措施)如果编译器没有名为X的函数的地址,它将(简单地说)在其对象输出中放入“X为空”,并期望链接器将其解析为实际地址。(链接器可以从同一个目标文件、不同的目标文件或库解析它。)“源代码从上到下读取”-在一个源文件中。但是C和C++都有单独的编译。一个文件中的行既不低于其他文件中的行,也不高于其他文件中的行。你看到的只是一个简单的问题。