使用cppcheck给工程代码做静态检查,主要发现了以下几个问题:
1.使用C风格的类型转换
警告如下:
C-style pointer casting detected. C++ offers four different kinds of casts as replacements: static_cast, const_cast, dynamic_cast and reinterpret_cast. A C-style cast could evaluate to any of those automatically, thus it is considered safer if the programmer explicitly states which kind of cast is expected. See also: https://www.securecoding.cert.org/confluence/display/cplusplus/EXP05-CPP.+Do+not+use+C-style+casts.
应该使用C++提供的static_cast, const_cast, dynamic_cast 和 reinterpret_cast 做类型转换,明确转换的类型。
2.迭代器使用后置叠加(叠减)运算符
警告如下:
Prefix ++/-- operators should be preferred for non-primitive types. Pre-increment/decrement can be more efficient than post-increment/decrement. Post-increment/decrement usually involves keeping a copy of the previous value around and adds a little extra code.
迭代器前置++和后置++ 的运行效率是不同的,前置++效率更高,因为后置运算符需要做一个临时的类对象拷贝。
3. 直接在函数参数中使用C风格字符串。
警告如下:
The conversion from const char* as returned by c_str() to std::string creates an unnecessary string copy. Solve that by directly passing the string.
比如一个函数的参数类型是strng,调用时实参直接使用了C风格的字符串,于是就会有以上提示,主要还是因为这里会造成一个不必要的字符串拷贝,降低运行效率。
4. 使用无用的find
很多时候,我们会写下面的find代码,值不等于-1则说明找到了该字符串,
if(std::string::npos != dataStr.find("what"))
//do something
该代码段会导致报警:
Either inefficient or wrong usage of string::find(). string::compare() will be faster if string::find‘s result is compared with 0, because it will not scan the whole string. If your intention is to check that there are no findings in the string, you should compare with std::string::npos.
代码本身不会出错,但是效率上是不被认可的,如cppcheck所说,如果你希望检查某个字符串是不是某个期望的字符串,那你应该使用compare函数,因为这样更快。
5. 函数参数使用传值而不是传引用
警告如下:
Parameter ‘strShowTime‘ is passed by value. It could be passed as a const reference which is usually faster and recommended in C++.
C++给了引用传参,而你不使用,那就是你的问题了。
6. 构造函数没有使用初始化成员变量列表,而是习惯于写入构造函数体
警告有:
Member variable ‘CActiveComboItemXml::m_phorActivecombo‘ is not initialized in the constructor.
或者如:
When an object of a class is created, the constructors of all member variables are called consecutively in the order the variables are declared, even if you don‘t explicitly write them to the initialization list. You could avoid assigning ‘m_strHrefOnPanReady‘ a value by passing the value to the constructor in the initialization list.
这个问题很普遍,因为很多程序员不习惯在构造函数的初始化列表中初始化成员变量,有的是直接忽略掉,有的则是在构造函数的函数体中去使用赋值运算符赋值,可是这个时候已经不是初始化了,而是赋值阶段了。这是个很危险的习惯!
这几个问题大量出现在cppcheck的问题列表中,是我们经常犯的编程问题,应从代码风格上进行规避。
当然了,可能的错误(警告)是由不当的编码风格和不扎实的C++编码基础导致的,通过静态检查我们自己的代码,可以最大层度的写出易读且不容易出错的代码。
推荐大家使用cppcheck!
原文地址:https://www.cnblogs.com/Stultz-Lee/p/10061365.html