Why did C++ never allow functions to be used before they're declared? [closed]

╄→гoц情女王★ 提交于 2019-12-03 17:11:33

问题


OK, I know this looks like a duplicate of Why do functions need to be declared before they are used? but it doesn't seem like existing answers fully address all the details.

I know that C++ was originally designed in the 80's so it could be translated in a single pass, because computers were slow. OK. But the most recent standard was published in 2011, so I don't see why C++ compilers can't do things now that require multiple passes. It would still hurt performance, yes, but only if it actually became necessary. So the following would still only require a single pass:

void foo();
int main() { foo(); }
void foo() {}

whereas for the following, the compiler could make two (and be slower), because it doesn't know whether foo is a function or a type until it sees the declaration below:

int main() { foo(); }
void foo() {}

and if you tried to use a function without declaring it first, and the declaration is not in the current translation unit at all, then it would be an error. But if it's in the same translation unit then the compiler could just make additional passes.

My colleague argues that such a feature would save a lot of developer time, and would avoid issues with the declaration and definition not being matched. And I'm sure this has been proposed many times over and rejected every time. What is the actual reasoning behind rejecting it, i.e., the committee's rationale?


回答1:


Template parsing

Consider the following line of code:

a < b , c > d;

How would you parse this? There are actually two ways, depending on what a, b, c and d are. Firstly, a variable declaration

a<b,c>   d;
^^^^^^   ^
 Type   Var

in the case that a is a known template type, b and c are other known types. Secondly,

   a<b   ,   c<d ;
   ^^^       ^^^ 
boolean expressions

in the case that a, b, c and d are all variables of some sort.

The vexing parse

Or here another one:

a b(c); // is 'b' a function or a variable?

This could be a function declaration (a function with return type a and argument type c) or a variable definition (whose type is a and whose constructor argument is c).

Conclusion

There's a lot of stuff like that, unfortunately. I'm not sure, if it would be impossible to write a compiler that can deal with that kind of stuff, but it would at least be very hard to write one. Compilation times are a serious issue in C++ already. This would only make it worse. Also: It is good practice to only use what you have defined or declared already, even in other languages.

Constraints of the committee

Even if it would be reasonably possible to implement this feature, it would kill backwards compatibility. Function overloading resolution only takes prior declarations into account and the interpretation of function calls may change depending on the place a function call is written. That's the way C++ is put together. Now, the C++ standards committee is big on back-wards compatibility. In particular: They do not want to break any existing code (and rightly so). Your proposal would surely break existing code which is a no-go for the language designers.




回答2:


The current answer is because it would be unparseable.

Consider two-phase name lookup for templates, and in particular the need for typename. In templates, type-dependent names may not have been declared yet. To be able to parse them, we absolutely need typename. Without that, parsing would grind to a halt and we can't reliably proceed, so we couldn't even provide the type needed to fix the parsing problem. It's a chicken and egg problem: If we need to have parsed line 10 to parse line 5, line 10 will never be parsed because we break at line 5. typename helps us get past line 5 so we can learn the actual type on line 10.

Here, we'd have a similar problem. Consider this code under your assumptions:

struct Foo { };
int bar () { return Foo(); }
int Foo () { return 42; }

To parse this code, we need to know whether Foo denotes a type or function.



来源:https://stackoverflow.com/questions/24925831/why-did-c-never-allow-functions-to-be-used-before-theyre-declared

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!