我不是要问各种可用的第三方模块以某种方式支持Cppcheck.
有了CMake 3.10,CMake似乎获得了一些官方的Cppcheck支持.请参阅CMAKE_ <LANG> _CPPCHECK.
不幸的是,如何使用这个变量的文档有点稀疏.是否有一个很好的例子说明Cppcheck应该如何与CMake 3.10(或更高版本)一起使用?
在最近的一次bug搜索中,我发现了一个返回指向临时变量成员的指针的问题.违规(简化)代码是:
struct S {
S(int i) : i(i) {}
int i;
int* ptr() { return &i; }
};
int* fun(int i) { return S(i).ptr(); } // temporary S dies but pointer lives on
int main() {
int* p = fun(1);
return *p; // undefined
}
Run Code Online (Sandbox Code Playgroud)
怎么预防这个?海湾合作委员会和铿锵有-Waddress-of-temporary,-Wreturn-stack-address但他们似乎因为ptr()肮脏的行为充当中间人而松散.它们仅在直接获取指针时触发:
int* fun(int i) { return &S(i).i; } // rightly fails to compile
Run Code Online (Sandbox Code Playgroud)
我的项目还将cppcheck整合到持续集成中,但它也无法获取(在这里提出).
哪种静态分析工具可以防止这类错误?
编辑:GCC确实从版本6.1.0开始接收-Wreturn-local-addr并且(令人惊讶地)-O2开启.
在代码审查期间,我找到了这样的源代码:
void f_odd(std::string &className, std::string &testName)
{
if (className.find("::") != std::string::npos)
{
testName = className.substr(className.find("::") + 2);
(void)className.erase(className.find("::"), std::string::npos);
}
}
Run Code Online (Sandbox Code Playgroud)
在这个函数中,std :: string :: find()被调用三次,具有相同的模式(这里是"::").
这个代码当然可以重构为
void f(std::string &className, std::string &testName)
{
const size_t endOfClassNamePos = className.find("::");
if (endOfClassNamePos != std::string::npos)
{
testName = className.substr(endOfClassNamePos + 2);
(void)className.erase(endOfClassNamePos, std::string::npos);
}
}
Run Code Online (Sandbox Code Playgroud)
find只被调用一次.
题
有人知道检测这种模式的策略吗?我有一个巨大的代码库,我打算发现这种模式.我计划使用Windows或Linux环境.
潜在的策略
没有Go
更新1
我决定从潜在的策略开始1).我打算让cppcheck适应这个问题.
Cppcheck提供了基于PCRE正则表达式编写自定义规则的可能性.为此,必须使用启用的PCRE支持编译cppcheck.由于当前测试环境是基于Linux的,因此可以使用以下命令下载最新版本的cppcheck:
git clone https://github.com/danmar/cppcheck.git && cd cppcheck
之后,编译并安装该工具,如下所示:
sudo make install HAVE_RULES=yes
现在基本工具设置完成了.为了开发一个cppcheck规则,我准备了一个简单的测试用例(file:test.cpp),类似于本文第一部分中的示例代码.此文件包含三个功能和cppcheck规则应在发出警告f_odd …
最近,我有以下情况
struct data {
std::vector<int> V;
};
data get_vector(int n)
{
std::vector<int> V(n,0);
return {V};
}
Run Code Online (Sandbox Code Playgroud)
这段代码的问题在于,在创建结构体时会发生一个副本,而解决方案是编写return {std::move(V)}
是否有可以检测这种虚假复制操作的 linter 或代码分析器?cppcheck、cpplint 和 clang-tidy 都做不到。
编辑:几点让我的问题更清楚:
Cppcheck在这样的代码中发现了一个潜在的问题:
float a, b, c;
int count = sscanf(data, "%f,%f,%f", &a, &b, &c);
Run Code Online (Sandbox Code Playgroud)
它说:"没有字段宽度限制的scanf可能会因大量数据而崩溃".怎么可能?这是某些sscanf实现中的已知错误吗?我知道数字可能会溢出(数字),但程序怎么会崩溃?这在cppcheck中是误报吗?
我发现了一个类似的问题:scanf Cppcheck警告,但答案并不完全令人满意.答案提到了类型安全,但这不应该是一个问题.
我在源代码库中调用cppcheck自己的文件.但是,一些源文件包含来自第三方库的头文件./lib/some_library/.这些也由cppcheck自动解析.
我不想要这个,因为我不想看到第三方代码的警告.有办法解决这个问题吗?
其区别我怎么能告诉cppcheck跳过一个头文件是,这个帖子确实需要跳过整个目录,而不是一个单独的头文件.
我正在使用Cppcheck来管理我的代码.我有以下功能:
bool my_function(std::string my_string) const
{
return 0 == my_string.compare("Some text"); // line 3
}
Run Code Online (Sandbox Code Playgroud)
令我惊讶的是,我在第3行得到了Null指针取消引用.
我完全感到困惑:我的功能中没有指针.为什么我会收到此错误?
我试过调查一下:
我检查了字符串my_string是否为空.
我使用"我的文本"创建了一个对象,以确保Cppcheck不会抱怨使用临时对象:
bool my_function(std::string my_string) const
{
std::string str("Some text");
return 0 == my_string.compare(str); // line 3
}
Run Code Online (Sandbox Code Playgroud)我还可以做些什么?是Cppcheck中的错误吗?比较功能本身有问题吗?如果是这种情况我会感到惊讶,因为cppcheck不会抱怨我的项目中使用的任何其他std函数.
我发现--suppress=unmatchedSuppression仅抑制 cppcheck 选项中不匹配的抑制类型,但不抑制不匹配的内联抑制。
这是预期的行为吗?
测试.c
第4行是错误的。应该予以警告arrayIndexOutOfBounds
7号线还可以。不应该被警告arrayIndexOutOfBounds
我cppcheck-suppress对两条线都有内联。
1 void f() {
2 char arr[5];
3 // cppcheck-suppress arrayIndexOutOfBounds
4 arr[10] = 0;
5
6 // cppcheck-suppress arrayIndexOutOfBounds
7 const char ok[] = "this line is ok";
8 }
Run Code Online (Sandbox Code Playgroud)
情况1
Suppress cstyleCast,它在代码中不存在。
cppcheck --inline-suppr --force --enable=all
--xml-version=2 --suppress=cstyleCast test.c
2>cppcheckresults.xml
Run Code Online (Sandbox Code Playgroud)
我收到警告(以及其他不相关的警告)
unmatchedSuppression: arrayIndexOutOfBounds在test.c line 7(如预期)
unmatchedSuppression: cstyleCast在* line 0(如预期)
情况2
与情况 1 相同,但有附加--suppress=unmatchedSuppression选项
cppcheck --inline-suppr …Run Code Online (Sandbox Code Playgroud) 我想制作一个cppcheck在Sensor类中运行工具的插件.为了重用现有的和支持的插件,我想使用sonar-cxx插件来导入我的插件的结果.
如何在声纳扫描仪中订购插件?我想确保在声纳扫描程序调用cxx-plugin之前创建了cppcheck报告.
我有一个半大的Visual Studio解决方案,具有一系列不同的构建配置和各种平台.我真的只想在一个平台上检查一个或两个配置.但是,当您使用--project标志时,我在CppCheck手册中没有看到选择构建配置的方法.我试过用--platform; 然而,这甚至不只是为该平台选择配置(win64仍然检查win32配置).
有没有办法让CppCheck在解决方案中选择单一的构建配置,或者甚至可能排除某些配置?