在最近的一次错误搜索中,我发现了一个返回指向临时变量成员的指针的问题。违规(简化)代码是:
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
}
如何防止这种情况? GCC& Clang有-Waddress-of-temporary
和-Wreturn-stack-address
,但由于ptr()
扮演肮脏行为的中间人,他们似乎松了一口气。它们仅在直接指针时触发:
int* fun(int i) { return &S(i).i; } // rightly fails to compile
我的项目还在持续集成中加入了cppcheck,但它也无法提取(募集here)。
哪种静态分析工具可以防止这类错误?
编辑:GCC确实从版本6.1.0开始接收-Wreturn-local-addr
并且(令人惊讶地)-O2
已启用。
答案 0 :(得分:3)
我是Cppcheck开发人员。
有趣的错误。这是cppcheck想要警告的那种bug。我们有一些相关的检查,但遗憾的是这个检查过了。我的项目还将cppcheck整合到持续集成中,但它也无法接收它。
鉴于cppcheck的正则表达性质,这并不奇怪。
我个人不理解为什么有人说cppcheck是一个正则表达式工具。
它使用AST,上下文敏感的值流分析等来检测错误。 GCC和Clang也是如此。有时声称Cppcheck是一个正则表达式工具,但GCC和Clang不是。