为什么C++在声明之前从不允许使用函数?

Bri*_*ian 14 c++ compiler-construction declaration c++11

好的,我知道这看起来像是复制了为什么在使用之前需要声明函数?但似乎现有答案并未完全解决所有细节问题.

我知道C++最初是在80年代设计的,所以它可以在一次通过中翻译,因为计算机很慢.好.但是最新的标准是在2011年发布的,所以我不明白为什么C++编译器现在不能做需要多次传递的事情.它仍然会伤害性能,是的,但只有在它真的变得必要的时候.所以以下内容仍然只需要一次传递:

void foo();
int main() { foo(); }
void foo() {}
Run Code Online (Sandbox Code Playgroud)

而对于以下情况,编译器可以使两个(并且更慢),因为它不知道foo是函数还是类型,直到它看到下面的声明:

int main() { foo(); }
void foo() {}
Run Code Online (Sandbox Code Playgroud)

如果你试图使用一个函数而不首先声明它,并且声明根本不在当前的翻译单元中,那么这将是一个错误.但是如果它在同一个翻译单元中,那么编译器可以只进行额外的传递.

我的同事辩称,这样的功能可以节省大量的开发人员时间,并且可以避免声明和定义不匹配的问题.而且我确信这已被多次提出并且每次都被拒绝.拒绝它的实际原因是什么,委员会的理由?

MSa*_*ers 1

当前的答案是因为它无法解析。

考虑模板的两阶段名称查找,特别typename. 在模板中,依赖于类型的名称可能尚未声明。为了能够解析它们,我们绝对需要typename. 如果没有这个,解析就会停止,我们就无法可靠地继续,所以我们甚至无法提供解决解析问题所需的类型。这是一个先有鸡还是先有蛋的问题:如果我们需要解析第 10 行来解析第 5 行,则第 10 行将永远不会被解析,因为我们在第 5 行处中断。typename帮助我们越过第 5 行,以便我们可以了解第 10 行的实际类型。

在这里,我们也会遇到类似的问题。根据您的假设考虑此代码:

struct Foo { };
int bar () { return Foo(); }
int Foo () { return 42; }
Run Code Online (Sandbox Code Playgroud)

为了解析这段代码,我们需要知道是否Foo表示类型或函数。

  • @Brian:请注意,您刚刚描述了一个 n 遍编译器。当 Foo 依赖于 Bar 依赖于 Baz 依赖于 ... 时,你可能会有任意数量的回溯。 (3认同)