我已经在C++编程了几个月了,当我经历论坛时,我发现了一个趋势。看来goto
声明通常被认为是完全错误的使用,或者应该只在非常特定的情况下使用。什么是goto
陈述,使他们从根本上错误?为什么goto语句在C++中被视为禁忌?
回答
最大的原因是它使代码难以遵循。 goto
并不是不好的;使用它编写难以编写的代码很容易。
例如,您宁愿阅读哪一个?这:
int factorial(int n) {
int result;
if(n==0 || n==1)
result = 1;
else
result = n*factorial(n-1);
return result;
}
或者这样:
int factorial(int n) {
int result;
if(n > 1)
goto big;
result = 1;
goto end;
big:
result = n*factorial(n-1);
end:
return result;
}
的两种实现方式是一样的机器,但首先是更清楚我们的人的眼睛。虽然有时候goto
是更清晰。例如,在C考虑这个(或C++没有例外):
void process_big_file(FILE* foo) {
if(possible_failure_1(foo))
goto cleanup;
// Do some work
if(possible_failure_2(foo))
goto cleanup;
// Do some more work
cleanup:
fclose(foo);
}
在这里,用goto
是有道理的,因为它可以让你把所有的清理代码在一个地方,和goto
5事实上创建的逻辑流程执行。特别是在阅读代码时,很明显,您总是(a)达到清理代码,并且(b)总是达到清理代码,这是重要的。在没有例外情况下,我实际上认为goto
在尝试组织(例如)清理代码时是正确的。
最后一个例子不应该在C++中使用。即使没有例外,您也始终拥有与错误代码/早期退货一起工作的RAII。 – Pubby 2013-04-28 18:42:45
作为一项规则,我同意,但有时RAII不适合。在这种情况下,你需要一个好的旧指针(甚至不需要'auto_ptr',它会为你实现RAII),然后你必须手动进行清理。一个很好的例子是带有循环引用的对象图,因为RAII类型对象和'auto_ptr'都使用(a)对象生命周期或(b)引用计数(分别)来执行清理。当然,有时候你会插入传统的C代码,然后所有的地狱都会崩溃。 :) – sigpwned 2013-04-28 18:48:12
@sigpwned最后一个例子是设计不佳的代码的一个完美例子,其中一个函数做得太多。 – 2013-04-28 19:00:50
主要原因是goto
使代码的推理非常困难,如果不是不可能的话。 (请注意,对于隐藏的goto也是如此,就像使用break
从循环中间退出一样。)通常,如果您想要推理代码的正确性,则需要输入每个块在顶部,并将其留在底部。如果没有能够推断代码的正确性,则无法确定它是否正确。
关于我所看到的主题的最佳解释。 – SChepurin 2013-04-29 05:28:43
- 1. 为什么全局变量被认为是“禁忌”语法?
- 2. 什么被认为是C++语句?
- 3. C#.NET中的GOTO语句
- 4. 为什么print语句不被执行?
- 5. 为什么if语句被忽略?
- 6. 为什么Visual C#中的if语句未被正确评估?
- 7. 为什么我的if语句中的条件被忽略? C#
- 8. Netezza GOTO语句
- 9. sql-goto语句
- 10. C#中的goto语句慢了吗?
- 11. 为什么bool在C++中不被视为boost :: true_type?
- 12. 为什么&在这个if语句中?
- 13. 为什么return语句不能在else语句中工作
- 14. 在try块java中返回语句。什么会被方法返回,为什么?
- 15. 为什么在Android Studio中使用import语句被指定为“unused import statement”?
- 16. 为什么在C++中的return语句后停止执行?
- 17. 在Java中替代goto语句
- 18. 为什么开关语句在案例
- 19. 为什么JavaScript有时会被视为低级语言?
- 20. 数学 - 为什么PHP中的微分微积分(MVP)是禁忌?
- 21. C++中的goto语句在堆栈中的效果
- 22. 为什么WebFrameLoadDelegate被视为未声明?
- 23. Javascript,为什么被视为八进制
- 24. 为什么*不被视为MathSymbol?
- 25. 为什么“strcat”被视为“不安全”?
- 26. 为什么if语句中的print语句没有运行?
- 27. 即将使用goto语句
- 28. 为什么C++被称为面向对象的编程语言?
- 29. 为什么我可以在C#中编写一个通用的catch语句,该语句什么都不做?
- 30. 为什么推送队列被禁用
您可能想从[这里]开始(http://en.wikipedia.org/wiki/Considered_harmful) – 2013-04-28 18:28:39
* goto *语句不是“根本错误” - 优化的汇编代码充满了跳转目的。但是* goto *使代码难以被人读取 - 对于一台机器来说什么是好的对于人来说通常不是那么好。 – SChepurin 2013-04-28 18:48:14
自20世纪60年代以来,Goto一直失宠。然而,一些着名作家,如Knuth,仍在使用它们。 – 2013-04-28 19:03:39