为什么有些内核程序员使用goto而不是简单的while循环?

当我学习C时,老师终日告诉我:“不要使用goto,这是一个坏习惯,它很丑,很危险!” 等等。

那么为什么一些内核程序员使用goto ,比如在这个函数中 ,可以用一个简单的replace

 while(condition) {} 

要么

 do {} while(condition); 

我不明白这一点。 在某些情况下使用goto而不是while / do会更好吗? 如果是这样,为什么?

在这个例子的情况下,我怀疑是将SMP支持改为最初以非SMP安全方式编写的代码。 goto again;添加一个goto again; path比重构function简单得多,侵入性也小一些。

我不能说我很喜欢这种风格,但是我也认为,为了避免意识形态的原因,要避免转向。 goto用法的一个特例(不同于这个例子)是goto只用于在一个函数中前进的地方,而不是后退。 这类用法从来不会导致goto所产生的循环结构,而且它几乎总是最简单,最清晰的方式来实现所需的行为(通常是清理并返回错误)。

历史背景:我们应该记住,Dijkstra在1968年写了“ Goto Considered Harmful” ,当时很多程序员都用goto代替了结构化编程 ( ifwhilefor等等)。

44年过去了,在野外find这个goto很less见。 结构化编程已经赢得了很久以前。

案例分析:

示例代码如下所示:

  SETUP... again: COMPUTE SOME VALUES... if (cmpxchg64(ptr, old_val, val) != old_val) goto again; 

结构化版本如下所示:

 SETUP... do { COMPUTE SOME VALUES... } while (cmpxchg64(ptr, old_val, val) != old_val); 

当我看结构化版本时,我立即想到,“这是一个循环”。 当我看到goto版本的时候,我认为这是一条直线,最后是一个“再试一次”的例子。

goto版本在同一列上同时具有SETUPCOMPUTE SOME VALUES ,强调大部分时间,控制stream都通过两者。 结构化版本将SETUPCOMPUTE SOME VALUES放在不同的列上,强调控制可以以不同的方式通过它们。

这里的问题是你想要在代码中强调什么样的? 您可以将其与goto进行比较以进行error handling:

结构版本:

 if (do_something() != ERR) { if (do_something2() != ERR) { if (do_something3() != ERR) { if (do_something4() != ERR) { ... 

转到版本:

 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; 

生成的代码基本上是一样的,所以我们可以把它看作是一个排版问题,比如缩进。