Bjö*_*lex 18 c++ function-declaration
在阅读这个问题的一些答案时,我开始想知道为什么编译器在第一次遇到函数时确实需要知道它.在解析收集在其中声明的所有符号的编译单元时添加额外的通道是不是很简单,这样它们的声明和使用顺序就不再重要了?
有人可能会争辩说,在使用它们之前声明函数肯定是好的风格,但我想知道,为什么在C++中这是强制性的还有其他原因?
编辑 - 举例说明:假设您必须在头文件中内联定义的函数.这两个函数相互调用(可能是递归树遍历,其中树的奇数层和偶数层的处理方式不同).解决这个问题的唯一方法是在另一个函数之前声明其中一个函数.
一个更常见的例子(虽然有类,而不是函数)是带有private构造函数和工厂的类的情况.工厂需要知道类以便创建它的实例,并且类需要知道工厂的friend声明.
如果要求来自以前的日子,为什么它在某些时候没有被删除?它不会破坏现有的代码,不是吗?
sbi*_*sbi 12
您如何建议解决在不同翻译单元中定义的未声明标识符?
C++没有模块概念,但是有单独的翻译作为C的继承.C++编译器将自己编译每个翻译单元,根本不了解其他翻译单元.(除了这export打破了这个,这可能是为什么它,但遗憾的是,从未起飞.)
头文件,你通常放置在其他翻译单元中定义的标识符的声明,实际上只是一个非常笨拙的滑动方式声明到不同的翻译单位.它们不会使编译器意识到存在其中具有标识符的其他转换单元.
编辑重新您的其他例子:
与所有的文本包含,而不是一个适当的模块概念,编制已经花费令人痛苦长,C++,所以需要另一个编译通(其中汇编已经被分成若干遍,不是所有的这些都可以进行优化和合并,IIRC)会使已经很糟糕的问题恶化.改变这种情况可能会在某些情况下改变重载决策,从而破坏现有代码.
请注意,C++确实需要额外的传递来解析类定义,因为类定义中内联定义的成员函数被解析为就好像它们是在类定义后面定义的一样.但是,这是在考虑C with Classes时决定的,因此没有现成的代码库可以打破.
小智 9
历史上C89让你这样做.编译器第一次看到函数的使用并且它没有预定义的原型时,它"创建"了一个与函数的使用相匹配的原型.
当C++决定在编译器中添加严格的类型检查时,就决定现在需要原型.此外,C++继承了C的单遍编译,因此无法添加第二遍来解析所有符号.