为什么需要前瞻性声明?

use*_*421 19 c c++ compiler-construction declaration

可能重复:
C++应该删除头文件吗?

在像C#和Java这样的语言中,没有必要在使用它之前声明(例如)一个类.如果我理解正确,这是因为编译器对代码进行了两次传递.在第一个中它只是"收集可用信息",在第二个中它检查代码是否正确.

在C和C++中,编译器只进行一次传递,因此当时所有东西都需要可用.

所以我的问题基本上就是为什么不用C和C++这样做.它不会消除头文件的需求吗?

Dan*_*ory 42

简短的回答是计算能力和资源在定义C的时间和Java在25年后出现的时间之间呈指数级增长.

答案越长......

编译单元的最大大小- 编译器在单个块中处理的代码块 - 将受编译计算机具有的内存量的限制.为了处理您在机器代码中键入的符号,编译器需要将所有符号保存在查找表中,并在代码中遇到它们时引用它们.

当C在1972年创建时,计算资源更加稀缺且高昂 - 在大多数系统中都无法立即存储复杂程序的整个符号表所需的内存.固定存储也很昂贵,并且非常慢,因此虚拟内存或在磁盘上存储符号表部分等想法根本不允许在合理的时间范围内进行编译.

解决这个问题的最佳方法是将代码分成更小的部分,方法是在需要时将符号表的哪些部分放在哪个编译单元中.向程序员强加一个相当小的任务来宣告他使用什么节省了计算机搜索整个程序以获得程序员可以使用的任何东西的巨大努力.

它还使编译器不必在每个源文件上进行两次传递:第一个用于索引内部的所有符号,第二个用于解析引用并查找它们.当你处理磁带时,在几秒钟内测量搜索时间,读取吞吐量以每秒字节数(不是千字节或兆字节)来衡量,这非常有意义.

C++虽然在大约17年后创建,但被定义为C的超集,因此必须使用相同的机制.

当Java在1995年推出时,平均计算机有足够的内存,即使对于复杂的项目,持有符号表也不再是一个沉重的负担.Java并不是为了与C语言向后兼容而设计的,因此它不需要采用传统机制.C#同样没有受到阻碍.

结果,他们的设计师选择将符号声明的划分负担从程序员身上移开并再次放在计算机上,因为它的成本与编译的总工作量成比例是最小的.

  • 优秀的总结.提醒我在2个软盘驱动器640K PC上编译C程序的"美好时光" - 用了6个或更多的软盘更改大约需要10分钟.对于一个包含不超过几百个语句的程序而言!并且以为我拥有所有这些力量在天堂. (7认同)
  • 很棒的答案,为年轻人提供一些历史视角总是很好的! (4认同)

Ran*_*pho 5

结论:编译器技术已经取得了进展,无需进行前向声明.加上计算机的速度要快几千倍,因此可以进行必要的额外计算以处理缺少前向声明的问题.

C和C++较旧,在需要保存每个CPU周期时都是标准化的.

  • 你错过了这里的关键词:向后兼容性.你的最后一行听起来像C和C++只有石版时代的标准版本.它应该是"并且*首先*标准化......并且为了保持向后兼容性,方法保持不变." @Franci:当你用C#编写操作系统时,来找我吧. (8认同)
  • :-)换句话说 - C#比C++好. (3认同)
  • @Franci:不......换句话说,现代语言编译器已经使前向声明过时,因为它们不必担心向后兼容性.它*可以用C++完成.在C#bud中编写硬件驱动程序很有乐趣. (3认同)
  • @GMan - 拯救独角兽:你有关于"第一次标准化"和"向后兼容性"的优秀观点.关于C#中的操作系统:我给你[Singularity](http://research.microsoft.com/en-us/projects/singularity/).现在,被授予,内核的一些性能关键部分是用C语言编写的,但考虑到内核的某些部分经常用汇编语言编写,我会说它们已经提升了一点. (2认同)