我继承了一个大的c ++代码库,我有一个任务是避免代码库中可能发生的任何空指针异常。是否有可用的静态分析工具,我在想,你已经成功使用了。
你还有什么其他的东西?
答案 0 :(得分:5)
您可以从消除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的优点,它无需在任何地方“尝试{}”,所以我认为值得您认真考虑。
答案 1 :(得分:2)
如果您主要维护代码库,那么您可以做的最低工作量和最高回报之一就是开始重构您的指针reference counted pointers。
我还会查看Purify之类的内容,它会检测代码以检测内存损坏。
答案 2 :(得分:2)
首先,作为技术问题,C ++没有NULL指针异常。取消引用NULL指针具有未定义的行为,并且在大多数系统上导致程序突然终止(“崩溃”)。
至于工具,我也推荐这个问题:
Are C++ static code analyis tools worth it?
特别是关于NULL指针解除引用,请考虑NULL指针解除引用有三个主要元素:
静态分析工具的难点部分当然是步骤2,工具的区别在于它们可以准确地(即,没有太多误报)轨道的复杂路径。查看一些您想要捕获的错误的具体示例可能会有用,以便更好地建议哪种工具最有效。
免责声明:我为Coverity工作。
答案 3 :(得分:2)
如果您不想更改任何代码,则必须使用某些工具(请参阅其他答案)。但是对于问题的一个特殊部分(你将一个指针放在一个函数中使用它),你可以使用一个很好的小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)
{ .. }
p.s:首先找到HERE,可以进一步调整
答案 4 :(得分:1)
这些可能是有意义的:
What open source C++ static analysis tools are available?
C++ static code analysis tool on Windows
Are C++ static code analyis tools worth it?
我还会考虑使用动态运行时工具,如Valgrind(免费)
答案 5 :(得分:1)
一个附带问题,是避免这些的目的,因为他们不希望客户看到崩溃?在许多情况下,空指针是应该立即处理的意外情况,但通常它们会像烫手山芋一样通过系统传递。
我曾经在一个代码库上工作,习惯是在进入函数时,首先检查是否有任何空指针,如果是,则返回。这个问题是当工具没有崩溃时,它最终会无声地生成坏数据。并且尝试调试这些问题很困难,因为在结果变得无法容忍或最终不得不表现出来之前,可能已经有很长时间通过许多函数传递了非法的空指针。
理想情况下,您至少在开发期间需要正确的断言,因此请考虑使用宏来隐藏或重新定义生成构建的断言