mus*_*tze 51 c linux loops goto linux-kernel
当我学习C语言时,老师终日告诉我:"不要使用goto,这是一个坏习惯,它很丑,很危险!" 等等.
那么,为什么一些内核程序员会使用goto
,例如在这个函数中,它可以用一个简单的替换
while(condition) {}
Run Code Online (Sandbox Code Playgroud)
要么
do {} while(condition);
Run Code Online (Sandbox Code Playgroud)
我无法理解.在某些情况下使用goto而不是while
/ do
- 更好while
吗?如果是这样,为什么?
Die*_*Epp 58
历史背景:我们应该记住,Dijkstra算法写后藤是有害于1968年,当时很多程序员使用goto
作为替代结构化程序设计(if
,while
,for
等).
这是44年之后,goto
在野外很难找到这种用途.很久以前,结构化编程已经赢得了胜利.
案例分析:
示例代码如下所示:
SETUP...
again:
COMPUTE SOME VALUES...
if (cmpxchg64(ptr, old_val, val) != old_val)
goto again;
Run Code Online (Sandbox Code Playgroud)
结构化版本如下所示:
SETUP...
do {
COMPUTE SOME VALUES...
} while (cmpxchg64(ptr, old_val, val) != old_val);
Run Code Online (Sandbox Code Playgroud)
当我看结构化版本时,我立刻想到,"这是一个循环".当我看到这个goto
版本时,我认为它是一条直线,最后会有"再试一次"的情况.
该goto
版本具有两个SETUP
并且COMPUTE SOME VALUES
在同一列上,强调大多数时间,控制流都通过两者.结构化版本看跌期权SETUP
,并COMPUTE SOME VALUES
在不同的栏目,其中强调控制可以通过它们不同.
这里的问题是你想在代码中加入什么样的重点?您可以将其与goto
错误处理进行比较:
结构化版本:
if (do_something() != ERR) {
if (do_something2() != ERR) {
if (do_something3() != ERR) {
if (do_something4() != ERR) {
...
Run Code Online (Sandbox Code Playgroud)
转到版本:
if (do_something() == ERR) // Straight line
goto error; // |
if (do_something2() == ERR) // |
goto error; // |
if (do_something3() == ERR) // |
goto error; // V
if (do_something4() == ERR) // emphasizes normal control flow
goto error;
Run Code Online (Sandbox Code Playgroud)
生成的代码基本相同,因此我们可以将其视为排版问题,如缩进.
R..*_*R.. 30
在这个例子中,我怀疑它是关于将SMP支持改进为最初以非SMP安全方式编写的代码.添加goto again;
路径比重构功能要简单得多,侵入性也小.
我不能说我喜欢这种风格,但我也认为goto
出于意识形态的原因而避免这种做法是错误的.一个特殊的goto
使用情况(与此示例不同)goto
是仅用于在函数中向前移动,而不是向后移动.这类用法从来不会产生循环结构goto
,并且它几乎总是最简单,最清晰的方式来实现所需的行为(通常是清理并返回错误).
归档时间: |
|
查看次数: |
11055 次 |
最近记录: |