【问题标题】:Can't compilers jump down to find definition of called function?编译器不能跳下来找到被调用函数的定义吗?
【发布时间】:2015-07-17 18:12:49
【问题描述】:

在 C++ 中,执行从 main() 的顶部开始。好的,我知道了。现在看看这个:

  #include <iostream>
   int main ()
   {
       int x;
       std::cin >> x;
       std::cout << add (x, x);
       return 0;
   }

   int add(int x, int y)
   {
         return x+y;
   }

编译器在执行这个程序时抛出一个错误。如果我将 add () 移到 main () 之上或使用前向声明,程序将被编译而没有任何错误。这是否意味着编译器无法从调用者函数跳转到调用者下方定义的被调用函数的定义。请原谅我的英语。

【问题讨论】:

    标签: c++ function forward-declaration function-prototypes


    【解决方案1】:

    当然,编译器可以提前扫描并找到函数定义。但是,C(以及扩展的 C++)的标准有很长的历史,可以追溯到由于对磁盘上文件的缓慢访问而对正在编译的代码进行第二次传递非常昂贵的时代。内存相对不足也是一个因素。

    这种考虑当然促成了在 C 中需要前向声明,而 C++ 继承了它。改变这个要求会给语言带来非常大的改变,使得将新程序向后移植到旧编译器变得更加困难。这并不意味着它不能在以后的某个时间完成,但目前还没有完成。

    【讨论】:

    • 实际上,C 直到 C99 才需要前向声明,所以你不能真的说 C++ 继承了 C 的要求。如果有的话,可能正好相反。 (C 确实有前向声明的可能性,但它们不是必需的。如果在此示例中将 cincout 分别替换为 scanfprintf,它将在 C99 之前的模式下编译。 )
    • @celticminstrel 我几乎可以肯定,在标准的 ANSI 版本中强烈建议使用前向声明 - 至少我记得编译器曾经对缺少前向声明发出警告。 C 确实允许缺少前向声明,但它假设函数是int,并且它的所有参数(如果有的话)都是int。按照今天的标准,这个假设是疯狂的,但在当时,它是一个很好的权宜之计,可以构建单通道编译器。
    • 他们可能被强烈建议,但仍然不是必需的。
    【解决方案2】:

    实际上,您可以强制编译器向前看,以保持代码整洁。您可以使用函数原型来执行此操作。在您的代码中,这看起来像:

    #include <iostream>
       int add(int x, int y);
    
       int main ()
       {
           int x;
           std::cin >> x;
           std::cout << add (x, x);
           return 0;
       }
    
       int add(int x, int y)
       {
           return x+y;
       }
    

    这告诉编译器存在一个名为 add 的函数,它接受两个 int 作为参数并返回一个 int。但由于它没有定义,它会在代码的其他地方查找。

    如果您将所需的每个函数原型都放在源代码的顶部,它可能会变得几乎与将每个函数定义都放在源代码的顶部一样难看,这就是人们使用头文件 (.h) 来存储它们的原因,通常。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-17
      • 2015-06-21
      • 2021-08-06
      • 2013-09-20
      • 2018-02-09
      相关资源
      最近更新 更多