GOTO仍然认为有害?
每个人都知道迪杰斯特拉给编辑的信件:去看看被认为有害的声明(这里也是.html文字记录和这里.pdf),并且自那时以来一直强大的推动,以尽可能避免goto声明。 尽管可以使用goto来生成不可维护,庞大的代码,但它仍然处于现代编程语言中。 即使是Scheme中先进的继续控制结构也可以被描述成一个复杂的goto。
什么情况下需要使用goto? 什么时候最好避免?
作为一个后续问题:C提供了一对函数setjmp和longjmp,它们提供了不仅在当前堆栈帧内而且在任何调用帧内跳转的功能。 这些被认为是危险的吗? 更危险?
迪杰斯特拉本人对这个称号感到后悔,对此他不负责任。 在EWD1308(也在这里.pdf)的最后,他写道:
最后是一个记录的小故事。 1968年,ACM通讯发表了一篇题为“goto声明被认为是有害的”的文本,后来几年这篇文章被引用频率最高,但令人遗憾的是,经常没有看到它的作者经常看到它标题,通过成为一个模板而成为了我的名气的基石:我们将看到几乎所有X都以“X被认为有害”为标题的各种文章,其中包括题为“Dijkstra认为有害”的文章。 但是发生了什么? 我已经提交了一个名为“ 反对goto声明的案例 ”的论文,为了加快发布,编辑变成了“给编辑的一封信”,在这个过程中,他给了它一个新的他自己发明的头衔! 编辑是Niklaus Wirth。
关于这个主题的经过深思熟虑的经典论文,与Dijkstra的论文相匹配,是由Donald E. Knuth撰写的结构化程序设计与语句。 阅读都有助于重新建立语境和对主题的非教条理解。 在本文中,Dijkstra对此案的看法被报道,并且更为强烈:
唐纳德E.克努特:我相信通过提出这样的观点,我并不认同迪克斯特拉的观点,因为他最近写了以下内容:“请不要陷入相信我非常讨厌[去声明] 我有一种令人不舒服的感觉,就是其他人正在把它变成一种宗教,好像编程的概念问题可以通过一个简单的编程技巧来解决! “
以下陈述是概括性的; 虽然总是有可能辩论例外,但它通常(以我的经验和谦逊的观点)是不值得冒险的。
上述脚注:
关于第2点,请考虑以下代码:
a = b + 1
/* do something with a */
在代码中的“做某事”时,我们可以高度置信地表明a
大于b
。 (是的,我忽略了未处理的整数溢出的可能性,让我们不要陷入一个简单的例子。)
另一方面,如果代码是这样读取的:
...
goto 10
...
a = b + 1
10: /* do something with a */
...
goto 10
...
标签10的多样性意味着我们必须更加努力地对a
和b
之间的关系充满信心。 (事实上,在一般情况下,它是不可否认的!)
关于第4点,代码中“去某处”的概念只是一个比喻。 除了电子和光子(用于废热)之外,CPU内部的任何地方都没有“真正的”走向。 有时候我们会放弃另一个更有用的比喻。 我记得遇到(几十年前!)一种语言在哪里
if (some condition) {
action-1
} else {
action-2
}
通过将action-1和action-2编译为非线性无参数例程,然后使用一个使用条件的布尔值调用其中一个的双参数VM操作码,在虚拟机上实现。 这个概念只是“选择现在调用的内容”而不是“去这里或去那里”。 再次,只是一个比喻的变化。
我的一位同事说,使用GOTO的唯一理由是,如果你将自己编程到一个角落,那么这是唯一的出路。 换句话说,提前进行适当的设计,您将不需要稍后使用GOTO。
我认为这部漫画很好地说明了这一点:“我可以重新调整程序的流程,或者使用一点'GOTO'来代替。” 当你设计不力时,GOTO是一个薄弱的出路。 Velociraptors捕食软弱动物。
有时可以使用GOTO作为单个函数内异常处理的替代方法:
if (f() == false) goto err_cleanup;
if (g() == false) goto err_cleanup;
if (h() == false) goto err_cleanup;
return;
err_cleanup:
...
COM代码似乎经常陷入这种模式。
链接地址: http://www.djcxy.com/p/53767.html