我们大多数人都知道循环不应该有非终止条件。例如,这个 C# 循环有一个非终止条件:i 的任何偶数值。这是一个明显的逻辑错误。
void CountByTwosStartingAt(byte i) { // If i is even, it never exceeds 254
for(; i < 255; i += 2) {
Console.WriteLine(i);
}
}
有时存在极不可能的极端情况,但在技术上构成非退出条件(堆栈溢出和内存不足错误除外)。假设您有一个函数可以计算流中连续零的数量:
int CountZeros(Stream s) {
int total = 0;
while(s.ReadByte() == 0) total++;
return total;
}
现在,假设你喂它这个东西:
class InfiniteEmptyStream:Stream
{
// ... Other members ...
public override int Read(byte[] buffer, int offset, int count) {
Array.Clear(buffer, offset, count); // Output zeros
return count; // Never returns -1 (end of stream)
}
}
或者更现实地说,可能是从外部硬件返回数据的流,在某些情况下可能会返回许多零(例如坐在您办公桌上的游戏控制器)。无论哪种方式,我们都有一个无限循环。这种特殊的非终止条件很突出,但有时它们不会。
一个完全真实的例子,就像我正在编写的应用程序一样。无穷无尽的零流将被反序列化为无限的“空”对象(直到集合类或 GC 抛出异常,因为我已经超过了 20 亿个项目)。但这将是一个完全出乎意料的情况(考虑到我的数据源)。
绝对没有非终止条件有多重要?这对“稳健性”有多大影响?如果它们只是“理论上”非终止(如果异常表示隐式终止条件是否可以),这是否重要?应用程序是否商业重要吗?如果是公开发行的?有问题的代码是否无法通过公共接口/API 访问是否重要?
编辑: 我最关心的一个问题是不可预见的逻辑错误,它可以创建非终止条件。通常,如果您确保没有非终止条件,您可以更优雅地识别或处理这些逻辑错误,但值得吗?什么时候?这是一个与信任正交的问题。