GOTO仍然被认为有害吗? [英] GOTO still considered harmful?

查看:183
本文介绍了GOTO仍然被认为有害吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

每个人都知道Dijkstra的给编辑的信:转至认为有害的陈述(另此处 .html成绩单和此处 .pdf),自那时以来一直在大力推动避免尽可能使用goto语句.尽管可以使用goto生成无法维护的庞大代码,但仍保留在 continuation 控制结构都可以描述为复杂的goto.

Everyone is aware of Dijkstra's Letters to the editor: go to statement considered harmful (also here .html transcript and here .pdf) and there has been a formidable push since that time to eschew the goto statement whenever possible. While it's possible to use goto to produce unmaintainable, sprawling code, it nevertheless remains in modern programming languages. Even the advanced continuation control structure in Scheme can be described as a sophisticated goto.

什么情况下需要使用goto?什么时候最好避免?

What circumstances warrant the use of goto? When is it best to avoid?

作为后续问题:C提供了一对函数setjmp和longjmp,这些函数不仅可以在当前堆栈帧中而且可以在任何调用帧中进行跳转.这些应该像goto一样被视为危险吗?更危险吗?

As a followup question: C provides a pair of functions, setjmp and longjmp, that provide the ability to goto not just within the current stack frame but within any of the calling frames. Should these be considered as dangerous as goto? More dangerous?

迪克斯特拉本人对那个头衔感到遗憾,对此他不负责.在

Dijkstra himself regretted that title, for which he was not responsible. At the end of EWD1308 (also here .pdf) he wrote:

最后是一个简短的故事. 1968年,ACM通讯部 在 title"已考虑的goto语句 有害",在以后的几年中 最常被引用, 遗憾的是,通常是作者 谁见过的东西都比它多 标题,成为了 通过成为模板而声名:起: 会看到下面的各种文章 标题为"X认为有害" 几乎所有X,包括一个标题为 "Dijkstra被认为是有害的".但 发生了什么事情?我已经提交了 标题为" goto语句 ",按顺序 为了加快发布速度, 编辑已更改为 编辑",在此过程中 给它一个新的头衔 发明!编辑是尼克劳斯 沃思.

Finally a short story for the record. In 1968, the Communications of the ACM published a text of mine under the title "The goto statement considered harmful", which in later years would be most frequently referenced, regrettably, however, often by authors who had seen no more of it than its title, which became a cornerstone of my fame by becoming a template: we would see all sorts of articles under the title "X considered harmful" for almost any X, including one titled "Dijkstra considered harmful". But what had happened? I had submitted a paper under the title "A case against the goto statement", which, in order to speed up its publication, the editor had changed into a "letter to the Editor", and in the process he had given it a new title of his own invention! The editor was Niklaus Wirth.

关于此主题的经过深思熟虑的经典论文与Dijkstra的论文相匹配,是.阅读既有助于重新建立上下文,也有助于对主题的非教条式理解.在本文中,Dijkstra对于此案的观点得到了报道,并且更加有力:

A well thought out classic paper about this topic, to be matched to that of Dijkstra, is Structured Programming with go to Statements, by Donald E. Knuth. Reading both helps to reestablish context and a non-dogmatic understanding of the subject. In this paper, Dijkstra's opinion on this case is reported and is even more strong:

Donald E. Knuth:我相信通过介绍这样一个 认为我实际上并不反对 自从Dijkstra的想法开始, 他最近写道: 请不要陷入陷阱 相信我非常 教条式的[去 陈述]. 我感到不舒服 感觉别人在制造 摆脱宗教,好像 编程的概念性问题 可以通过一个技巧解决, 一种简单的编码规则形式!"

Donald E. Knuth: I believe that by presenting such a view I am not in fact disagreeing sharply with Dijkstra's ideas, since he recently wrote the following: "Please don't fall into the trap of believing that I am terribly dogmatical about [the go to statement]. I have the uncomfortable feeling that others are making a religion out of it, as if the conceptual problems of programming could be solved by a single trick, by a simple form of coding discipline!"

推荐答案

以下语句是概括;尽管总是可以提出例外请求,但通常(以我的经验和拙见)不值得冒险.

The following statements are generalizations; while it is always possible to plead exception, it usually (in my experience and humble opinion) isn't worth the risks.

  1. 不受限制地使用内存地址(GOTO或原始指针)提供了太多机会来避免容易避免的错误.
  2. 在代码中到达特定位置"的方法越多,对于该点系统状态的信心就越差. (请参见下文.)
  3. 结构化编程IMHO不太关注避免GOTO",而更多地在于使代码的结构与数据的结构匹配.例如,重复的数据结构(例如,数组,顺序文件等)由重复的代码单元自然地处理.具有内置的结构(例如,while,for,直到,for-each等),可使程序员避免重复相同的代码模式的繁琐工作.
  4. 即使GOTO是底层实现细节(并非总是如此!)也低于程序员应该考虑的水平.有多少程序员在原始二进制文件中平衡他们的个人支票簿?有多少程序员担心磁盘上的哪个扇区包含特定记录,而不仅仅是提供数据库引擎的密钥(如果我们真的按照物理磁盘扇区来编写所有程序,会出错多少种方式)?

上面的脚注:

关于第2点,请考虑以下代码:

Regarding point 2, consider the following code:

a = b + 1
/* do something with a */

在代码中的执行某些操作"点,我们可以高度肯定地声明a大于b. (是的,我忽略了无限整数溢出的可能性.我们不要简单地举一个简单的例子.)

At the "do something" point in the code, we can state with high confidence that a is greater than b. (Yes, I'm ignoring the possibility of untrapped integer overflow. Let's not bog down a simple example.)

另一方面,如果代码是这样读取的:

On the other hand, if the code had read this way:

...
goto 10
...
a = b + 1
10: /* do something with a */
...
goto 10
...

获得10标签的方式多种多样,这意味着我们必须更加努力才能对ab之间的关系充满信心. (实际上,在一般情况下这是无法确定的!)

The multiplicity of ways to get to label 10 means that we have to work much harder to be confident about the relationships between a and b at that point. (In fact, in the general case it's undecideable!)

关于第4点,代码中去某个地方"的整个概念只是一个隐喻.除了电子和光子(用于废热)之外,CPU内的任何地方都没有真正的去".有时,我们放弃了另一个更有用的隐喻.我记得(几十年前!)遇到过一种语言,

Regarding point 4, the whole notion of "going someplace" in the code is just a metaphor. Nothing is really "going" anywhere inside the CPU except electrons and photons (for the waste heat). Sometimes we give up a metaphor for another, more useful, one. I recall encountering (a few decades ago!) a language where

if (some condition) {
  action-1
} else {
  action-2
}

是通过将action-1和action-2编译为离线无参数例程在虚拟机上实现的,然后使用单个两个参数的VM操作码,该操作码使用条件的布尔值来调用一个或另一个.这个概念只是选择现在要调用的内容",而不是去这里或去那里".同样,只是隐喻的改变.

was implemented on a virtual machine by compiling action-1 and action-2 as out-of-line parameterless routines, then using a single two-argument VM opcode which used the boolean value of the condition to invoke one or the other. The concept was simply "choose what to invoke now" rather than "go here or go there". Again, just a change of metaphor.

这篇关于GOTO仍然被认为有害吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆