[英]Avoiding null pointer exceptions in a large c++ code base
我继承了一个大的c ++代码库,我有一个任务,以避免代码库中可能发生的任何空指针异常。 是否有可用的静态分析工具,我在想,你已经成功使用了。
你还有什么其他的东西?
您可以从消除NULL源开始:
更改
if (error) {
return NULL;
}
成
if (error) {
return DefaultObject; // Ex: an empty vector
}
如果返回的默认对象不适用且您的代码库已经使用了异常,请执行
if (error) {
throw BadThingHappenedException;
}
然后,在适当的位置添加处理。
如果您正在使用遗留代码,您可以创建一些包装函数/类:
ResultType *new_function() {
ResultType *result = legacy_function();
if (result) {
return result;
} else {
throw BadThingHappenedException;
}
}
新功能应该开始使用新功能并具有适当的异常处理。
我知道一些程序员不会得到例外,包括像Joel这样的聪明人。 但是,通过返回NULL最终发生的事情是,这个NULL会像疯了一样传递,因为每个人都会认为处理它并静默返回并不是他们的事。 某些函数可能会返回错误代码,这很好,但是调用者通常最终会返回NULL-another-NULL以响应错误。 然后,无论函数多么微不足道,您都会在每个函数中看到很多NULL检查。 并且,只需要一个不检查NULL以使程序崩溃的地方。 例外情况迫使您仔细考虑错误并确定应该在何处以及如何处理错误。
您似乎只是在寻找简单的解决方案,例如静态分析工具(您应该经常使用)。 更改引用指针也是一个很好的解决方案。 但是,C ++具有RAII的优点,它无需在任何地方“尝试{}”,所以我认为值得您认真考虑。
首先,作为技术问题,C ++没有NULL指针异常。 取消引用NULL指针具有未定义的行为,并且在大多数系统上导致程序突然终止(“崩溃”)。
至于工具,我也推荐这个问题:
特别是关于NULL指针解引用,请考虑NULL指针取消引用有三个主要元素:
静态分析工具的难点当然是步骤2,工具的区别在于它们可以准确地(即,没有太多误报)轨道的复杂路径。 查看一些您想要捕获的错误的具体示例可能会有用,以便更好地建议哪种工具最有效。
免责声明:我为Coverity工作。
如果您不想更改任何代码,则必须使用某些工具(请参阅其他答案)。 但是对于问题的一个特殊部分(你将一个指针放在一个函数中使用它),你可以使用一个很好的小Makro-Definition来找到一些小Buggers :(在发布模式下没有时间开销并添加一个可见的条件的代码)
#ifdef NDEBUG
#define NotNull(X) X
#else // in Debug-Mode
template<typename T> class NotNull;
template<typename T> // template specialization only for pointer-types
class NotNull<T*> {
public:
NotNull(T* object)
: _object(object) {
assert(object);
}
operator T*() const {
return _object;
}
T* operator->() const {
return _object;
}
private:
T *_object;
};
#define NotNull(X) NotNull<X>
#endif // in Debug-Mode
您只需更改此功能:
void increase(int* counter)
{ .. }
对此
void increase(NotNull(int*) counter)
{ .. }
ps:首先在这里找到了,可以进一步调整
这些可能是有趣的:
我还会看一下使用像Valgrind这样的动态运行时工具(免费)
一个侧面问题,是避免这些的目的,因为他们不希望客户看到崩溃? 在许多情况下,空指针是应该立即处理的意外情况,但是它们常常像热土豆一样通过系统传递。
我曾经在一个代码库上工作,习惯是在进入函数时,首先检查是否有任何空指针,如果是,则返回。 这个问题是当工具没有崩溃时,它最终会无声地生成坏数据。 并且尝试调试这些问题很困难,因为在结果变得无法容忍或最终不得不表现出来之前,可能已经有很长时间通过许多函数传递了非法的空指针。
理想情况下,您至少在开发期间需要适当的断言,因此请考虑使用宏来隐藏或重新定义生成构建的断言
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.