【发布时间】:2010-03-19 02:54:42
【问题描述】:
想象一下我有一个带有错误的函数:
伪代码:
void Foo(LPVOID o)
{
//implementation details omitted
}
问题是用户通过null:
Object bar = null;
...
Foo(bar);
那么函数可能由于访问冲突而崩溃;但它也可能会正常工作。错误是函数应该一直在检查传递null的无效情况,但它从来没有这样做过。这从来不是问题,因为相信开发人员知道他们在做什么。
如果我现在将函数更改为:
伪代码:
void Foo(LPVOID o)
{
if (o == null) throw new EArgumentNullException("o");
//implementation details omitted
}
然后那些愉快地使用该功能的人,碰巧但没有遇到访问冲突,现在突然会开始看到EArgumentNullException。
我是否继续让人们不正确地使用该功能,并创建该功能的新版本?或者我是否修复了该功能以包含它最初应该具有的功能?
所以现在是道德困境。您是否曾经向现有代码添加新的健全性检查、安全检查、断言?还是说放弃旧功能,换新功能?
考虑一个如此常见的错误,以至于微软不得不为开发人员修复它:
MessageBox(GetDesktopWindow, ...);
您永远、永远、永远都不想在桌面上制作一个窗口模型。你会锁定系统。您是否继续让开发人员锁定用户的计算机?还是把函数改成:
MessageBox(HWND hWndParent, ...)
{
if (hWndParent == GetDesktopWindow)
throw new Exception("hWndParent cannot be the desktop window. Use NULL instead.");
...
}
实际上微软更改了窗口管理器以自动修复错误参数:
MessageBox(HWND hWndParent, ...)
{
if (hWndParent == GetDesktopWindow)
hWndParent = 0;
...
}
在我编造的例子中,没有办法修补函数 - 如果没有给我一个对象,我就不能做我需要做的事情。
您是否冒着通过添加参数验证来破坏现有代码的风险?您是否让现有代码继续出错,得到不正确的结果?
【问题讨论】: